llvm.org GIT mirror llvm / d9fc1ce
Fix 12513: Loop unrolling breaks with indirect branches. Take this opportunity to generalize the indirectbr bailout logic for loop transformations. CFG transformations will never get indirectbr right, and there's no point trying. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154386 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Trick 8 years ago
6 changed file(s) with 75 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
593593 /// normal form.
594594 bool isLoopSimplifyForm() const;
595595
596 /// isSafeToClone - Return true if the loop body is safe to clone in practice.
597 bool isSafeToClone() const;
598
596599 /// hasDedicatedExits - Return true if no exit block for the loop
597600 /// has a predecessor that is outside the loop.
598601 bool hasDedicatedExits() const;
204204 return getLoopPreheader() && getLoopLatch() && hasDedicatedExits();
205205 }
206206
207 /// isSafeToClone - Return true if the loop body is safe to clone in practice.
208 /// Routines that reform the loop CFG and split edges often fail on indirectbr.
209 bool Loop::isSafeToClone() const {
210 // Return false if any loop blocks contain indirectbrs.
211 for (Loop::block_iterator I = block_begin(), E = block_end(); I != E; ++I) {
212 if (isa((*I)->getTerminator()))
213 return false;
214 }
215 return true;
216 }
217
207218 /// hasDedicatedExits - Return true if no exit block for the loop
208219 /// has a predecessor that is outside the loop.
209220 bool Loop::hasDedicatedExits() const {
191191 loopPreheader = currentLoop->getLoopPreheader();
192192 }
193193
194 /// HasIndirectBrsInPreds - Returns true if there are predecessors, that are
195 /// terminated with indirect branch instruction.
196 bool HasIndirectBrsInPreds(const SmallVectorImpl &ExitBlocks);
197
198194 /// Split all of the edges from inside the loop to their exit blocks.
199195 /// Update the appropriate Phi nodes as we do so.
200196 void SplitExitEdges(Loop *L, const SmallVector &ExitBlocks);
202198 bool UnswitchIfProfitable(Value *LoopCond, Constant *Val);
203199 void UnswitchTrivialCondition(Loop *L, Value *Cond, Constant *Val,
204200 BasicBlock *ExitBlock);
205 bool UnswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L);
201 void UnswitchNontrivialCondition(Value *LIC, Constant *OnVal, Loop *L);
206202
207203 void RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
208204 Constant *Val, bool isEqual);
406402
407403 // If LoopSimplify was unable to form a preheader, don't do any unswitching.
408404 if (!loopPreheader)
405 return false;
406
407 // Loops with indirectbr cannot be cloned.
408 if (!currentLoop->isSafeToClone())
409 return false;
410
411 // Without dedicated exits, splitting the exit edge may fail.
412 if (!currentLoop->hasDedicatedExits())
409413 return false;
410414
411415 LLVMContext &Context = loopHeader->getContext();
637641 if (OptimizeForSize || F->hasFnAttr(Attribute::OptimizeForSize))
638642 return false;
639643
640 return UnswitchNontrivialCondition(LoopCond, Val, currentLoop);
644 UnswitchNontrivialCondition(LoopCond, Val, currentLoop);
645 return true;
641646 }
642647
643648 /// CloneLoop - Recursively clone the specified loop and all of its children,
732737 ++NumTrivial;
733738 }
734739
735 /// HasIndirectBrsInPreds - Returns true if there are predecessors, that are
736 /// terminated with indirect branch instruction.
737 bool LoopUnswitch::HasIndirectBrsInPreds(
738 const SmallVectorImpl &ExitBlocks){
739
740 for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) {
741 const BasicBlock *ExitBlock = ExitBlocks[i];
742 for (const_pred_iterator p = pred_begin(ExitBlock), e = pred_end(ExitBlock);
743 p != e; ++p) {
744 // Cannot split an edge from an IndirectBrInst
745 if (isa((*p)->getTerminator()))
746 return true;
747
748 }
749 }
750 return false;
751 }
752
753740 /// SplitExitEdges - Split all of the edges from inside the loop to their exit
754741 /// blocks. Update the appropriate Phi nodes as we do so.
755742 void LoopUnswitch::SplitExitEdges(Loop *L,
775762 /// UnswitchNontrivialCondition - We determined that the loop is profitable
776763 /// to unswitch when LIC equal Val. Split it into loop versions and test the
777764 /// condition outside of either loop. Return the loops created as Out1/Out2.
778 bool LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
765 void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
779766 Loop *L) {
780767 Function *F = loopHeader->getParent();
781768 DEBUG(dbgs() << "loop-unswitch: Unswitching loop %"
799786
800787 SmallVector ExitBlocks;
801788 L->getUniqueExitBlocks(ExitBlocks);
802 if (HasIndirectBrsInPreds(ExitBlocks))
803 return false;
804789
805790 // Split all of the edges from inside the loop to their exit blocks. Update
806791 // the appropriate Phi nodes as we do so.
915900 if (!LoopProcessWorklist.empty() && LoopProcessWorklist.back() == NewLoop &&
916901 LICHandle && !isa(LICHandle))
917902 RewriteLoopBodyWithConditionConstant(NewLoop, LICHandle, Val, true);
918
919 return true;
920903 }
921904
922905 /// RemoveFromWorklist - Remove all instances of I from the worklist vector
148148 return false;
149149 }
150150
151 // Loops with indirectbr cannot be cloned.
152 if (!L->isSafeToClone()) {
153 DEBUG(dbgs() << " Can't unroll; Loop body cannot be cloned.\n");
154 return false;
155 }
156
151157 BasicBlock *Header = L->getHeader();
152158 BranchInst *BI = dyn_cast(LatchBlock->getTerminator());
153159
0 ; RUN: opt < %s -S -loop-unroll -simplifycfg | FileCheck %s
1 ; PR12513: Loop unrolling breaks with indirect branches.
2 ; If loop unrolling attempts to transform this loop, it replaces the
3 ; indirectbr successors. SimplifyCFG then considers them to be unreachable.
4 declare void @subtract() nounwind uwtable
5
6 ; CHECK-NOT: unreachable
7 define i32 @main(i32 %argc, i8** nocapture %argv) nounwind uwtable {
8 entry:
9 %vals19 = alloca [5 x i32], align 16
10 %x20 = alloca i32, align 4
11 store i32 135, i32* %x20, align 4
12 br label %for.body
13
14 for.body: ; preds = ; %call2_termjoin, %call3_termjoin
15 %indvars.iv = phi i64 [ 0, %entry ], [ %joinphi15.in.in, %call2_termjoin ]
16 %a6 = call coldcc i8* @funca(i8* blockaddress(@main, %for.body_code), i8*
17 blockaddress(@main, %for.body_codeprime)) nounwind
18 indirectbr i8* %a6, [label %for.body_code, label %for.body_codeprime]
19
20 for.body_code: ; preds = %for.body
21 call void @subtract()
22 br label %call2_termjoin
23
24 call2_termjoin: ; preds = %for.body_codeprime, %for.body_code
25 %joinphi15.in.in = add i64 %indvars.iv, 1
26 %exitcond = icmp eq i64 %joinphi15.in.in, 5
27 br i1 %exitcond, label %for.end, label %for.body
28
29 for.end: ; preds = %call2_termjoin
30 ret i32 0
31
32 for.body_codeprime: ; preds = %for.body
33 call void @subtract_v2(i64 %indvars.iv)
34 br label %call2_termjoin
35 }
36
37 declare coldcc i8* @funca(i8*, i8*) readonly
38
39 declare void @subtract_v2(i64) nounwind uwtable
None ; RUN: opt -loop-unswitch -disable-output -stats -info-output-file - < %s | FileCheck --check-prefix=STATS %s
1 ; RUN: opt -S -loop-unswitch -verify-loop-info -verify-dom-info %s | FileCheck %s
2
3 ; STATS: 1 loop-unswitch - Total number of instructions analyzed
0 ; RUN: opt < %s -S -loop-unswitch -verify-loop-info -verify-dom-info | FileCheck %s
1 ; PR12343: -loop-unswitch crash on indirect branch
42
53 ; CHECK: %0 = icmp eq i64 undef, 0
64 ; CHECK-NEXT: br i1 %0, label %"5", label %"4"
75
86 ; CHECK: "5": ; preds = %entry
9 ; CHECK-NEXT: br label %"5.split"
10
11 ; CHECK: "5.split": ; preds = %"5"
127 ; CHECK-NEXT: br label %"16"
138
14 ; CHECK: "16": ; preds = %"22", %"5.split"
9 ; CHECK: "16": ; preds = %"22", %"5"
1510 ; CHECK-NEXT: indirectbr i8* undef, [label %"22", label %"33"]
1611
1712 ; CHECK: "22": ; preds = %"16"