llvm.org GIT mirror llvm / 8d9ac7f
Generalize MergeBlockIntoPredecessor. Replace uses of MergeBasicBlockIntoOnlyPred. Summary: Two utils methods have essentially the same functionality. This is an attempt to merge them into one. 1. lib/Transforms/Utils/Local.cpp : MergeBasicBlockIntoOnlyPred 2. lib/Transforms/Utils/BasicBlockUtils.cpp : MergeBlockIntoPredecessor Prior to the patch: 1. MergeBasicBlockIntoOnlyPred Updates either DomTree or DeferredDominance Moves all instructions from Pred to BB, deletes Pred Asserts BB has single predecessor If address was taken, replace the block address with constant 1 (?) 2. MergeBlockIntoPredecessor Updates DomTree, LoopInfo and MemoryDependenceResults Moves all instruction from BB to Pred, deletes BB Returns if doesn't have a single predecessor Returns if BB's address was taken After the patch: Method 2. MergeBlockIntoPredecessor is attempting to become the new default: Updates DomTree or DeferredDominance, and LoopInfo and MemoryDependenceResults Moves all instruction from BB to Pred, deletes BB Returns if doesn't have a single predecessor Returns if BB's address was taken Uses of MergeBasicBlockIntoOnlyPred that need to be replaced: 1. lib/Transforms/Scalar/LoopSimplifyCFG.cpp Updated in this patch. No challenges. 2. lib/CodeGen/CodeGenPrepare.cpp Updated in this patch. i. eliminateFallThrough is straightforward, but I added using a temporary array to avoid the iterator invalidation. ii. eliminateMostlyEmptyBlock(s) methods also now use a temporary array for blocks Some interesting aspects: - Since Pred is not deleted (BB is), the entry block does not need updating. - The entry block was being updated with the deleted block in eliminateMostlyEmptyBlock. Added assert to make obvious that BB=SinglePred. - isMergingEmptyBlockProfitable assumes BB is the one to be deleted. - eliminateMostlyEmptyBlock(BB) does not delete BB on one path, it deletes its unique predecessor instead. - adding some test owner as subscribers for the interesting tests modified: test/CodeGen/X86/avx-cmp.ll test/CodeGen/AMDGPU/nested-loop-conditions.ll test/CodeGen/AMDGPU/si-annotate-cf.ll test/CodeGen/X86/hoist-spill.ll test/CodeGen/X86/2006-11-17-IllegalMove.ll 3. lib/Transforms/Scalar/JumpThreading.cpp Not covered in this patch. It is the only use case using the DeferredDominance. I would defer to Brian Rzycki to make this replacement. Reviewers: chandlerc, spatel, davide, brzycki, bkramer, javed.absar Subscribers: qcolombet, sanjoy, nemanjai, nhaehnle, jlebar, tpr, kbarton, RKSimon, wmi, arsenm, llvm-commits Differential Revision: https://reviews.llvm.org/D48202 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335183 91177308-0d34-0410-b5e6-96231b3b80d8 Alina Sbirlea 1 year, 2 months ago
34 changed file(s) with 133 addition(s) and 108 deletion(s). Raw diff Collapse all Expand all
5757 /// value indicates success or failure.
5858 bool MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT = nullptr,
5959 LoopInfo *LI = nullptr,
60 MemoryDependenceResults *MemDep = nullptr);
60 MemoryDependenceResults *MemDep = nullptr,
61 DeferredDominance *DDT = nullptr);
6162
6263 /// Replace all uses of an instruction (specified by BI) with a value, then
6364 /// remove and delete the original instruction.
515515 bool CodeGenPrepare::eliminateFallThrough(Function &F) {
516516 bool Changed = false;
517517 // Scan all of the blocks in the function, except for the entry block.
518 for (Function::iterator I = std::next(F.begin()), E = F.end(); I != E;) {
519 BasicBlock *BB = &*I++;
518 // Use a temporary array to avoid iterator being invalidated when
519 // deleting blocks.
520 SmallVector Blocks;
521 for (auto &Block : llvm::make_range(std::next(F.begin()), F.end()))
522 Blocks.push_back(&Block);
523
524 for (auto &Block : Blocks) {
525 auto *BB = cast_or_null(Block);
526 if (!BB)
527 continue;
520528 // If the destination block has a single pred, then this is a trivial
521529 // edge, just collapse it.
522530 BasicBlock *SinglePred = BB->getSinglePredecessor();
527535 BranchInst *Term = dyn_cast(SinglePred->getTerminator());
528536 if (Term && !Term->isConditional()) {
529537 Changed = true;
530 LLVM_DEBUG(dbgs() << "To merge:\n" << *SinglePred << "\n\n\n");
531 // Remember if SinglePred was the entry block of the function.
532 // If so, we will need to move BB back to the entry position.
533 bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock();
534 MergeBasicBlockIntoOnlyPred(BB, nullptr);
535
536 if (isEntry && BB != &BB->getParent()->getEntryBlock())
537 BB->moveBefore(&BB->getParent()->getEntryBlock());
538
539 // We have erased a block. Update the iterator.
540 I = BB->getIterator();
538 LLVM_DEBUG(dbgs() << "To merge:\n" << *BB << "\n\n\n");
539
540 // Merge BB into SinglePred and delete it.
541 MergeBlockIntoPredecessor(BB);
541542 }
542543 }
543544 return Changed;
590591 }
591592
592593 bool MadeChange = false;
594 // Copy blocks into a temporary array to avoid iterator invalidation issues
595 // as we remove them.
593596 // Note that this intentionally skips the entry block.
594 for (Function::iterator I = std::next(F.begin()), E = F.end(); I != E;) {
595 BasicBlock *BB = &*I++;
597 SmallVector Blocks;
598 for (auto &Block : llvm::make_range(std::next(F.begin()), F.end()))
599 Blocks.push_back(&Block);
600
601 for (auto &Block : Blocks) {
602 BasicBlock *BB = cast_or_null(Block);
603 if (!BB)
604 continue;
596605 BasicBlock *DestBB = findDestBlockOfMergeableEmptyBlock(BB);
597606 if (!DestBB ||
598607 !isMergingEmptyBlockProfitable(BB, DestBB, Preheaders.count(BB)))
761770 // just collapse it.
762771 if (BasicBlock *SinglePred = DestBB->getSinglePredecessor()) {
763772 if (SinglePred != DestBB) {
764 // Remember if SinglePred was the entry block of the function. If so, we
765 // will need to move BB back to the entry position.
766 bool isEntry = SinglePred == &SinglePred->getParent()->getEntryBlock();
767 MergeBasicBlockIntoOnlyPred(DestBB, nullptr);
768
769 if (isEntry && BB != &BB->getParent()->getEntryBlock())
770 BB->moveBefore(&BB->getParent()->getEntryBlock());
771
772 LLVM_DEBUG(dbgs() << "AFTER:\n" << *DestBB << "\n\n\n");
773 assert(SinglePred == BB &&
774 "Single predecessor not the same as predecessor");
775 // Merge DestBB into SinglePred/BB and delete it.
776 MergeBlockIntoPredecessor(DestBB);
777 // Note: BB(=SinglePred) will not be deleted on this path.
778 // DestBB(=its single successor) is the one that was deleted.
779 LLVM_DEBUG(dbgs() << "AFTER:\n" << *SinglePred << "\n\n\n");
773780 return;
774781 }
775782 }
2626 #include "llvm/Analysis/ScalarEvolution.h"
2727 #include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
2828 #include "llvm/Analysis/TargetTransformInfo.h"
29 #include "llvm/Transforms/Utils/Local.h"
3029 #include "llvm/IR/Dominators.h"
3130 #include "llvm/Transforms/Scalar.h"
3231 #include "llvm/Transforms/Scalar/LoopPassManager.h"
3332 #include "llvm/Transforms/Utils.h"
33 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
34 #include "llvm/Transforms/Utils/Local.h"
3435 #include "llvm/Transforms/Utils/LoopUtils.h"
3536 using namespace llvm;
3637
5455 if (!Pred || !Pred->getSingleSuccessor() || LI.getLoopFor(Pred) != &L)
5556 continue;
5657
57 // Pred is going to disappear, so we need to update the loop info.
58 if (L.getHeader() == Pred)
59 L.moveToHeader(Succ);
60 LI.removeBlock(Pred);
61 MergeBasicBlockIntoOnlyPred(Succ, &DT);
58 // Merge Succ into Pred and delete it.
59 MergeBlockIntoPredecessor(Succ, &DT, &LI);
6260
6361 SE.forgetLoop(&L);
6462 Changed = true;
116116
117117 bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT,
118118 LoopInfo *LI,
119 MemoryDependenceResults *MemDep) {
120 // Don't merge away blocks who have their address taken.
121 if (BB->hasAddressTaken()) return false;
119 MemoryDependenceResults *MemDep,
120 DeferredDominance *DDT) {
121 assert(!(DT && DDT) && "Cannot call with both DT and DDT.");
122
123 if (BB->hasAddressTaken())
124 return false;
122125
123126 // Can't merge if there are multiple predecessors, or no predecessors.
124127 BasicBlock *PredBB = BB->getUniquePredecessor();
130133 if (PredBB->getTerminator()->isExceptional())
131134 return false;
132135
133 succ_iterator SI(succ_begin(PredBB)), SE(succ_end(PredBB));
134 BasicBlock *OnlySucc = BB;
135 for (; SI != SE; ++SI)
136 if (*SI != OnlySucc) {
137 OnlySucc = nullptr; // There are multiple distinct successors!
138 break;
139 }
140
141 // Can't merge if there are multiple successors.
142 if (!OnlySucc) return false;
136 // Can't merge if there are multiple distinct successors.
137 if (PredBB->getUniqueSuccessor() != BB)
138 return false;
143139
144140 // Can't merge if there is PHI loop.
145141 for (PHINode &PN : BB->phis())
155151 cast(PN.getIncomingValue(0))->getParent() != BB)
156152 IncomingValues.push_back(PN.getIncomingValue(0));
157153 FoldSingleEntryPHINodes(BB, MemDep);
154 }
155
156 // Deferred DT update: Collect all the edges that exit BB. These
157 // dominator edges will be redirected from Pred.
158 std::vector Updates;
159 if (DDT) {
160 Updates.reserve(1 + (2 * succ_size(BB)));
161 Updates.push_back({DominatorTree::Delete, PredBB, BB});
162 for (auto I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
163 Updates.push_back({DominatorTree::Delete, BB, *I});
164 Updates.push_back({DominatorTree::Insert, PredBB, *I});
165 }
158166 }
159167
160168 // Delete the unconditional branch from the predecessor...
203211 if (MemDep)
204212 MemDep->invalidateCachedPredecessors();
205213
206 BB->eraseFromParent();
214 if (DDT) {
215 DDT->deleteBB(BB); // Deferred deletion of BB.
216 DDT->applyUpdates(Updates);
217 } else {
218 BB->eraseFromParent(); // Nuke BB.
219 }
207220 return true;
208221 }
209222
440440 ; GCN-NEXT: s_xor_b64 exec, exec, [[TEMP_MASK1]]
441441 ; GCN-NEXT: ; mask branch [[RET:BB[0-9]+_[0-9]+]]
442442
443 ; GCN: [[LOOP_BODY:BB[0-9]+_[0-9]+]]: ; %loop_body
443 ; GCN: [[LOOP_BODY:BB[0-9]+_[0-9]+]]: ; %loop
444444 ; GCN: ;;#ASMSTART
445445 ; GCN: v_nop_e64
446446 ; GCN: v_nop_e64
451451 ; GCN: ;;#ASMEND
452452 ; GCN: s_cbranch_vccz [[RET]]
453453
454 ; GCN-NEXT: [[LONGBB:BB[0-9]+_[0-9]+]]: ; %loop_body
454 ; GCN-NEXT: [[LONGBB:BB[0-9]+_[0-9]+]]: ; %loop
455455 ; GCN-NEXT: ; in Loop: Header=[[LOOP_BODY]] Depth=1
456456 ; GCN-NEXT: s_getpc_b64 vcc
457457 ; GCN-NEXT: s_sub_u32 vcc_lo, vcc_lo, ([[LONGBB]]+4)-[[LOOP_BODY]]
5858
5959 ; GCN-LABEL: {{^}}reduced_nested_loop_conditions:
6060
61 ; GCN: s_cmp_eq_u32 s{{[0-9]+}}, 1
62 ; GCN-NEXT: s_cbranch_scc1
61 ; GCN: s_cmp_lg_u32 s{{[0-9]+}}, 1
62 ; GCN-NEXT: s_cbranch_scc0
6363
6464 ; FIXME: Should fold to unconditional branch?
6565 ; GCN: ; implicit-def
66 ; GCN: s_cbranch_vccz
66 ; GCN: s_cbranch_vccnz
6767
6868 ; GCN: ds_read_b32
6969
8888
8989 ; This broke the old AMDIL cfg structurizer
9090 ; FUNC-LABEL: {{^}}loop_land_info_assert:
91 ; SI: s_cmp_gt_i32
92 ; SI-NEXT: s_cbranch_scc0 [[ENDPGM:BB[0-9]+_[0-9]+]]
91 ; SI: s_cmp_lt_i32
92 ; SI-NEXT: s_cbranch_scc1 [[ENDPGM:BB[0-9]+_[0-9]+]]
9393
94 ; SI: s_cmpk_gt_i32
95 ; SI-NEXT: s_cbranch_scc1 [[ENDPGM]]
94 ; SI: s_cmpk_lt_i32
95 ; SI-NEXT: s_cbranch_scc0 [[ENDPGM]]
9696
9797 ; SI: [[INFLOOP:BB[0-9]+_[0-9]+]]
9898 ; SI: s_cbranch_vccnz [[INFLOOP]]
4646 br label %L2
4747
4848 L2: ; preds = %L3, %bb2
49 ; THUMB-LABEL: %L1.clone
49 ; THUMB-LABEL: %.split4
5050 ; THUMB: muls
5151 %res.2 = phi i32 [ %res.1, %L3 ], [ 1, %bb2 ] ; [#uses=1]
5252 %phitmp = mul i32 %res.2, 6 ; [#uses=1]
159159 ; Validate with memcmp()?:
160160 define signext i32 @equalityFoldTwoConstants() {
161161 ; CHECK-LABEL: equalityFoldTwoConstants:
162 ; CHECK: # %bb.0: # %endblock
162 ; CHECK: # %bb.0: # %loadbb
163163 ; CHECK-NEXT: li 3, 1
164164 ; CHECK-NEXT: blr
165165 %call = tail call signext i32 @memcmp(i8* bitcast ([15 x i32]* @zeroEqualityTest04.buffer1 to i8*), i8* bitcast ([15 x i32]* @zeroEqualityTest04.buffer2 to i8*), i64 16)
66
77 define zeroext i1 @opeq1(
88 ; PPC64LE-LABEL: opeq1:
9 ; PPC64LE: # %bb.0: # %opeq1.exit
9 ; PPC64LE: # %bb.0: # %entry
1010 ; PPC64LE-NEXT: ld 3, 0(3)
1111 ; PPC64LE-NEXT: ld 4, 0(4)
1212 ; PPC64LE-NEXT: xor 3, 3, 4
168168 ; CHECK-NEXT: bne 0, .[[LOOP]]
169169 ;
170170 ; Next BB
171 ; CHECK: %for.end
171 ; CHECK: %for.exit
172172 ; CHECK: mtlr {{[0-9]+}}
173173 ; CHECK-NEXT: blr
174174 define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) {
22 ; RUN: -ppc-convert-rr-to-ri -verify-machineinstrs | FileCheck %s
33 define void @test(i32 zeroext %parts) {
44 ; CHECK-LABEL: test:
5 ; CHECK: # %bb.0: # %cond.end.i
5 ; CHECK: # %bb.0: # %entry
66 ; CHECK-NEXT: cmplwi 0, 3, 1
77 ; CHECK-NEXT: bnelr+ 0
88 ; CHECK-NEXT: # %bb.1: # %test2.exit.us.unr-lcssa
2424 br i1 undef, label %return, label %bb
2525
2626 return:
27 ; CHECK: %return
27 ; CHECK: %bb3
2828 ; 'mov sp, r7' would have left sp in an invalid state
2929 ; CHECK-NOT: mov sp, r7
3030 ; CHECK-NOT: sub, sp, #4
1212 ; CHECK-NOT: data_region
1313 entry:
1414 br i1 %b, label %codeRepl127.exitStub, label %newFuncRoot
15
16 newFuncRoot:
17 br label %_getopt_internal.exit.ce
1815
1916 codeRepl127.exitStub: ; preds = %_getopt_internal.exit.ce
2017 ; Add an explicit edge back to before the jump table to ensure this block
10299 codeRepl103.exitStub: ; preds = %_getopt_internal.exit.ce
103100 ret i16 26
104101
102 newFuncRoot:
103 br label %_getopt_internal.exit.ce
104
105105 _getopt_internal.exit.ce: ; preds = %newFuncRoot
106106 switch i32 %0, label %codeRepl127.exitStub [
107107 i32 -1, label %parse_options.exit.loopexit.exitStub
55 ; CHECK: # %bb.0: # %entry
66 ; CHECK-NEXT: movl 0, %eax
77 ; CHECK-NEXT: decl %eax
8 ; CHECK-NEXT: cmpl $2, %eax
9 ; CHECK-NEXT: jae .LBB0_2
10 ; CHECK-NEXT: # %bb.1: # %cond_next129
8 ; CHECK-NEXT: cmpl $1, %eax
9 ; CHECK-NEXT: ja .LBB0_2
10 ; CHECK-NEXT: # %bb.1: # %bb77
1111 ; CHECK-NEXT: movb 0, %al
1212 ; CHECK-NEXT: movzbl %al, %eax
1313 ; CHECK-NEXT: # kill: def $eax killed $eax def $ax
2525 define void @render() nounwind {
2626 ; CHECK-LABEL: render:
2727 ; CHECK: # %bb.0: # %entry
28 ; CHECK-NEXT: pushq %rbp
2829 ; CHECK-NEXT: pushq %rbx
30 ; CHECK-NEXT: pushq %rax
2931 ; CHECK-NEXT: xorl %eax, %eax
3032 ; CHECK-NEXT: testb %al, %al
3133 ; CHECK-NEXT: jne .LBB2_6
3234 ; CHECK-NEXT: # %bb.1: # %for.cond5.preheader
3335 ; CHECK-NEXT: xorl %ebx, %ebx
36 ; CHECK-NEXT: movb $1, %bpl
3437 ; CHECK-NEXT: jmp .LBB2_2
3538 ; CHECK-NEXT: .p2align 4, 0x90
3639 ; CHECK-NEXT: .LBB2_5: # %if.then
4245 ; CHECK-NEXT: jne .LBB2_2
4346 ; CHECK-NEXT: # %bb.3: # %for.cond5
4447 ; CHECK-NEXT: # in Loop: Header=BB2_2 Depth=1
45 ; CHECK-NEXT: testb %bl, %bl
46 ; CHECK-NEXT: je .LBB2_2
48 ; CHECK-NEXT: testb %bpl, %bpl
49 ; CHECK-NEXT: jne .LBB2_2
4750 ; CHECK-NEXT: # %bb.4: # %for.body33
4851 ; CHECK-NEXT: # in Loop: Header=BB2_2 Depth=1
4952 ; CHECK-NEXT: vucomisd {{\.LCPI.*}}, %xmm0
5154 ; CHECK-NEXT: jp .LBB2_5
5255 ; CHECK-NEXT: jmp .LBB2_2
5356 ; CHECK-NEXT: .LBB2_6: # %for.end52
57 ; CHECK-NEXT: addq $8, %rsp
5458 ; CHECK-NEXT: popq %rbx
59 ; CHECK-NEXT: popq %rbp
5560 ; CHECK-NEXT: retq
5661 entry:
5762 br i1 undef, label %for.cond5, label %for.end52
5757 ;
5858 define <8 x float> @funcE() nounwind {
5959 ; CHECK-LABEL: funcE:
60 ; CHECK: # %bb.0: # %for_exit499
60 ; CHECK: # %bb.0: # %allocas
6161 ; CHECK-NEXT: xorl %eax, %eax
6262 ; CHECK-NEXT: testb %al, %al
6363 ; CHECK-NEXT: # implicit-def: $ymm0
685685 ; X32-NEXT: ## %bb.2: ## %ret
686686 ; X32-NEXT: retl
687687 ; X32-NEXT: .p2align 4, 0x90
688 ; X32-NEXT: LBB33_1: ## %footer349VF
688 ; X32-NEXT: LBB33_1: ## %footer329VF
689689 ; X32-NEXT: ## =>This Inner Loop Header: Depth=1
690690 ; X32-NEXT: jmp LBB33_1
691691 ;
697697 ; X64-NEXT: ## %bb.2: ## %ret
698698 ; X64-NEXT: retq
699699 ; X64-NEXT: .p2align 4, 0x90
700 ; X64-NEXT: LBB33_1: ## %footer349VF
700 ; X64-NEXT: LBB33_1: ## %footer329VF
701701 ; X64-NEXT: ## =>This Inner Loop Header: Depth=1
702702 ; X64-NEXT: jmp LBB33_1
703703 WGLoopsEntry:
66
77 define void @func() {
88 ; CHECK-LABEL: func:
9 ; CHECK: # %bb.0: # %L_10
9 ; CHECK: # %bb.0: # %bb1
1010 ; CHECK-NEXT: xorl %eax, %eax
1111 ; CHECK-NEXT: testb %al, %al
1212 ; CHECK-NEXT: je .LBB0_1
6969 ; CHECK-NEXT: je .LBB1_1
7070 ; CHECK-NEXT: # %bb.2: # %if.then
7171 ; CHECK-NEXT: jmp bar # TAILCALL
72 ; CHECK-NEXT: .LBB1_1: # %return
72 ; CHECK-NEXT: .LBB1_1: # %if.end
7373 ; CHECK-NEXT: movzbl %dil, %eax
7474 ; CHECK-NEXT: orq $-2, %rax
7575 ; CHECK-NEXT: retq
316316 ; a function. This is a gross CFG reduced out of the single source GCC.
317317 ; CHECK-LABEL: unnatural_cfg1
318318 ; CHECK: %entry
319 ; CHECK: %loop.body1
319 ; CHECK: %loop.header
320320 ; CHECK: %loop.body2
321321 ; CHECK: %loop.body3
322322
610610 ; CHECK-LABEL: test_unnatural_cfg_backwards_inner_loop
611611 ; CHECK: %entry
612612 ; CHECK: %loop2b
613 ; CHECK: %loop1
613 ; CHECK: %loop3
614614
615615 entry:
616616 br i1 undef, label %loop2a, label %body
4747 %cmp326 = icmp sgt i32 %k.0, %p1
4848 br i1 %cmp326, label %for.cond4.preheader, label %for.body.preheader
4949
50 for.body.preheader: ; preds = %for.cond
51 br label %for.body
52
5350 for.cond4.preheader: ; preds = %for.body, %for.cond
5451 %k.1.lcssa = phi i32 [ %k.0, %for.cond ], [ %add, %for.body ]
5552 %cmp528 = icmp sgt i32 %sub., %p1
9491 middle.block: ; preds = %vector.body, %vector.body.preheader.split
9592 br i1 undef, label %for.inc14, label %for.body6
9693
94 for.body.preheader: ; preds = %for.cond
95 br label %for.body
96
9797 for.body: ; preds = %for.body, %for.body.preheader
9898 %k.127 = phi i32 [ %k.0, %for.body.preheader ], [ %add, %for.body ]
9999 %add = add nsw i32 %k.127, 1
22
33 define fastcc i32 @t() nounwind {
44 ; CHECK-LABEL: t:
5 ; CHECK: # %bb.0: # %walkExprTree.exit
5 ; CHECK: # %bb.0: # %entry
66 ; CHECK-NEXT: movzwl 0, %eax
77 ; CHECK-NEXT: orl $2, %eax
88 ; CHECK-NEXT: movw %ax, 0
77
88 define zeroext i1 @opeq1(
99 ; X86-LABEL: opeq1:
10 ; X86: # %bb.0: # %opeq1.exit
10 ; X86: # %bb.0: # %entry
1111 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
1212 ; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
1313 ; X86-NEXT: movl (%ecx), %edx
1919 ; X86-NEXT: retl
2020 ;
2121 ; X64-LABEL: opeq1:
22 ; X64: # %bb.0: # %opeq1.exit
22 ; X64: # %bb.0: # %entry
2323 ; X64-NEXT: movq (%rdi), %rax
2424 ; X64-NEXT: cmpq (%rsi), %rax
2525 ; X64-NEXT: sete %al
22
33 define void @pr32108() {
44 ; CHECK-LABEL: pr32108:
5 ; CHECK: # %bb.0: # %CF257
5 ; CHECK: # %bb.0: # %BB
66 ; CHECK-NEXT: movb $0, -{{[0-9]+}}(%rsp)
77 ; CHECK-NEXT: .p2align 4, 0x90
88 ; CHECK-NEXT: .LBB0_1: # %CF244
4242
4343 define void @pr26232(i64 %a, <16 x i1> %b) {
4444 ; AVX-LABEL: pr26232:
45 ; AVX: # %bb.0: # %for_loop599.preheader
45 ; AVX: # %bb.0: # %allocas
4646 ; AVX-NEXT: vpxor %xmm1, %xmm1, %xmm1
4747 ; AVX-NEXT: vmovdqa {{.*#+}} xmm2 = [128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128]
4848 ; AVX-NEXT: .p2align 4, 0x90
6363 ; AVX-NEXT: retq
6464 ;
6565 ; KNL-32-LABEL: pr26232:
66 ; KNL-32: # %bb.0: # %for_loop599.preheader
66 ; KNL-32: # %bb.0: # %allocas
6767 ; KNL-32-NEXT: pushl %esi
6868 ; KNL-32-NEXT: .cfi_def_cfa_offset 8
6969 ; KNL-32-NEXT: .cfi_offset %esi, -8
231231
232232 define void @mbb_int32_float_pair(i32 %tmp1, float %tmp2, i64* %ref.tmp) {
233233 ; CHECK-LABEL: mbb_int32_float_pair:
234 ; CHECK: # %bb.0: # %next
234 ; CHECK: # %bb.0: # %entry
235235 ; CHECK-NEXT: movl %edi, (%rsi)
236236 ; CHECK-NEXT: movss %xmm0, 4(%rsi)
237237 ; CHECK-NEXT: retq
249249
250250 define void @mbb_int32_float_multi_stores(i32 %tmp1, float %tmp2, i64* %ref.tmp, i64* %ref.tmp1, i1 %cmp) {
251251 ; CHECK-LABEL: mbb_int32_float_multi_stores:
252 ; CHECK: # %bb.0: # %bb1
252 ; CHECK: # %bb.0: # %entry
253253 ; CHECK-NEXT: movl %edi, (%rsi)
254254 ; CHECK-NEXT: movss %xmm0, 4(%rsi)
255255 ; CHECK-NEXT: testb $1, %cl
99 ; CHECK-NOT: # %{{[a-zA-Z_]+}}
1010 ; CHECK: # %inner_loop_latch
1111 ; CHECK-NOT: # %{{[a-zA-Z_]+}}
12 ; CHECK: # %inner_loop_test
12 ; CHECK: # %inner_loop_top
1313 ; CHECK-NOT: # %{{[a-zA-Z_]+}}
1414 ; CHECK: # %exit
1515 define void @tail_dup_merge_loops(i32 %a, i8* %b, i8* %c) local_unnamed_addr #0 {
77 ; We check that the compare instruction retains its debug loc after
88 ; it is sunk into other.bb by the codegen prepare pass.
99 ;
10 ; CHECK: other.bb:
10 ; CHECK: entry:
1111 ; CHECK-NEXT: icmp{{.*}}%x, 0, !dbg ![[MDHANDLE:[0-9]*]]
1212 ; CHECK: ![[MDHANDLE]] = !DILocation(line: 2
1313 ;
167167 ; the block it terminates.
168168 define void @loop(i64* nocapture readonly %p) {
169169 ; CHECK-LABEL: @loop(
170 ; CHECK-NEXT: bb0.clone:
170 ; CHECK-NEXT: entry:
171171 ; CHECK-NEXT: br label [[DOTSPLIT:%.*]]
172172 ; CHECK: bb0:
173173 ; CHECK-NEXT: br label [[DOTSPLIT]]
1212 %1 = icmp ugt i64 %0, 3
1313 br i1 %1, label %T, label %trap
1414
15 ; CHECK: T:
15 ; CHECK: entry:
1616 ; CHECK-NOT: br label %
1717
1818 trap: ; preds = %0, %entry
55 define void @t_run_test() {
66 ; CHECK-LABEL: @t_run_test(
77 ; CHECK-NEXT: entry:
8 ; CHECK-NEXT: br label [[LOOP_PH:%.*]]
9 ; CHECK: loop.ph:
10 ; CHECK-NEXT: br label [[LOOP_BODY:%.*]]
11 ; CHECK: loop.body:
12 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP_PH]] ], [ [[INC:%.*]], [[LOOP_BODY]] ]
8 ; CHECK-NEXT: br label %[[LOOP_PH:.*]]
9 ; CHECK: [[LOOP_PH]]:
10 ; CHECK-NEXT: br label %[[LOOP_BODY:.*]]
11 ; CHECK: [[LOOP_BODY]]:
12 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[LOOP_PH]] ], [ [[INC:%.*]], %[[LOOP_BODY]] ]
1313 ; CHECK-NEXT: [[INC]] = add i32 [[IV]], 1
1414 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC]], 10
15 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_BODY]], label [[EXIT:%.*]]
16 ; CHECK: exit:
17 ; CHECK-NEXT: br label [[LOOP_BODY2:%.*]]
18 ; CHECK: loop.body2:
19 ; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 0, [[EXIT]] ], [ [[INC2:%.*]], [[LOOP_BODY2]] ]
15 ; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP_BODY]], label %[[EXIT:.*]]
16 ; CHECK: [[EXIT]]:
17 ; CHECK-NEXT: br label %[[LOOP_BODY2:.*]]
18 ; CHECK: [[LOOP_BODY2]]:
19 ; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 0, %[[EXIT]] ], [ [[INC2:%.*]], %[[LOOP_BODY2]] ]
2020 ; CHECK-NEXT: [[INC2]] = add i32 [[IV2]], 1
2121 ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[INC2]], 10
22 ; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP_BODY2]], label [[EXIT2:%.*]]
23 ; CHECK: exit2:
22 ; CHECK-NEXT: br i1 [[CMP2]], label %[[LOOP_BODY2]], label %[[EXIT2:.*]]
23 ; CHECK: [[EXIT2]]:
2424 ; CHECK-NEXT: ret void
2525 ;
2626 entry:
4343
4444 ; CHECK: @main
4545 ; Check that the loop preheader contains no address computation.
46 ; CHECK: %end_of_chain
46 ; CHECK: %while.cond.i.i
4747 ; CHECK-NOT: add{{.*}}lsl
4848 ; CHECK: ldr{{.*}}lsl #2
4949 ; CHECK: ldr{{.*}}lsl #2
9595 ; itself a phi.
9696 ;
9797 ; CHECK: @test3
98 ; CHECK: %for.body3.lr.ph.us.i.loopexit
98 ; CHECK: %meshBB1
99 ; CHECK: %meshBB
99100 ; CHECK-NEXT: Parent Loop
100101 ; CHECK-NEXT: Inner Loop
101102 ; CHECK-NEXT: incq
1212 ; CHECK-NEXT: br i1 %{{.*}}, label %entry.split.split, label %loop_exit
1313 ;
1414 ; CHECK: entry.split.split:
15 ; CHECK-NEXT: br label %do_something
15 ; CHECK-NEXT: br label %loop_begin
1616
1717 loop_begin:
1818 br i1 %cond1, label %continue, label %loop_exit ; first trivial condition
2626 do_something:
2727 call void @some_func() noreturn nounwind
2828 br label %loop_begin
29 ; CHECK: do_something:
29 ; CHECK: loop_begin:
3030 ; CHECK-NEXT: call
31 ; CHECK-NEXT: br label %do_something
31 ; CHECK-NEXT: br label %loop_begin
3232
3333 loop_exit:
3434 ret i32 0
3737 ;
3838 ; CHECK: loop_exit.split:
3939 ; CHECK-NEXT: ret
40 }
40 }