llvm.org GIT mirror llvm / 3432f06
[Loop Peeling] Fix the bug with IDom setting for exit loops It is possible that loop exit has two predecessors in a loop body. In this case after the peeling the iDom of the exit should be a clone of iDom of original exit but no a clone of a block coming to this exit. Reviewers: reames, fhahn Reviewed By: reames Subscribers: hiraditya, zzheng, llvm-commits Differential Revision: https://reviews.llvm.org/D64618 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366050 91177308-0d34-0410-b5e6-96231b3b80d8 Serguei Katkov a month ago
2 changed file(s) with 73 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
581581 BasicBlock *Latch = L->getLoopLatch();
582582 SmallVector, 4> ExitEdges;
583583 L->getExitEdges(ExitEdges);
584
585 DenseMap ExitIDom;
586 if (DT) {
587 assert(L->hasDedicatedExits() && "No dedicated exits?");
588 for (auto Edge : ExitEdges) {
589 if (ExitIDom.count(Edge.second))
590 continue;
591 BasicBlock *BB = DT->getNode(Edge.second)->getIDom()->getBlock();
592 assert(L->contains(BB) && "IDom is not in a loop");
593 ExitIDom[Edge.second] = BB;
594 }
595 }
584596
585597 Function *F = Header->getParent();
586598
674686 // latter is the first cloned loop body, as original PreHeader dominates
675687 // the original loop body.
676688 if (Iter == 0)
677 for (auto Edge : ExitEdges)
678 DT->changeImmediateDominator(Edge.second,
679 cast(LVMap[Edge.first]));
689 for (auto Exit : ExitIDom)
690 DT->changeImmediateDominator(Exit.first,
691 cast(LVMap[Exit.second]));
680692 #ifdef EXPENSIVE_CHECKS
681693 assert(DT->verify(DominatorTree::VerificationLevel::Fast));
682694 #endif
718730 // We modified the loop, update SE.
719731 SE->forgetTopmostLoop(L);
720732
733 // Finally DomtTree must be correct.
734 assert(DT->verify(DominatorTree::VerificationLevel::Fast));
735
721736 // FIXME: Incrementally update loop-simplify
722737 simplifyLoop(L, DT, LI, SE, AC, nullptr, PreserveLCSSA);
723738
0 ; REQUIRES: asserts
1 ; RUN: opt < %s -S -debug-only=loop-unroll -loop-unroll -unroll-runtime -unroll-peel-multi-deopt-exit 2>&1 | FileCheck %s
2 ; RUN: opt < %s -S -debug-only=loop-unroll -unroll-peel-multi-deopt-exit -passes='require,function(require,unroll)' 2>&1 | FileCheck %s
3
4 ; Regression test for setting the correct idom for exit blocks.
5
6 ; CHECK: Loop Unroll: F[basic]
7 ; CHECK: PEELING loop %for.body with iteration count 1!
8
9 define i32 @basic(i32* %p, i32 %k, i1 %c1, i1 %c2) #0 !prof !3 {
10 entry:
11 %cmp3 = icmp slt i32 0, %k
12 br i1 %cmp3, label %for.body.lr.ph, label %for.end
13
14 for.body.lr.ph: ; preds = %entry
15 br label %for.body
16
17 for.body: ; preds = %for.body.lr.ph, %for.body
18 %i.05 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %latch ]
19 %p.addr.04 = phi i32* [ %p, %for.body.lr.ph ], [ %incdec.ptr, %latch ]
20 %incdec.ptr = getelementptr inbounds i32, i32* %p.addr.04, i32 1
21 store i32 %i.05, i32* %p.addr.04, align 4
22 %inc = add nsw i32 %i.05, 1
23 %cmp = icmp slt i32 %inc, %k
24 br i1 %c1, label %continue, label %to_side_exit
25
26 continue:
27 br i1 %c2, label %latch, label %side_exit, !prof !2
28
29 latch:
30 br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge, !prof !1
31
32 for.cond.for.end_crit_edge: ; preds = %for.body
33 br label %for.end
34
35 to_side_exit:
36 br i1 %c2, label %continue, label %side_exit, !prof !2
37
38
39 for.end: ; preds = %for.cond.for.end_crit_edge, %entry
40 %res = phi i32 [ 0, %entry ], [ %inc, %for.cond.for.end_crit_edge ]
41 ret i32 %res
42
43 side_exit:
44 %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %inc) ]
45 ret i32 %rval
46 }
47
48 declare i32 @llvm.experimental.deoptimize.i32(...)
49
50 attributes #0 = { nounwind }
51
52 !1 = !{!"branch_weights", i32 1, i32 1}
53 !2 = !{!"branch_weights", i32 1, i32 0}
54 !3 = !{!"function_entry_count", i64 1}