summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp
diff options
context:
space:
mode:
authorSerguei Katkov <serguei.katkov@azul.com>2019-07-15 09:13:11 +0000
committerSerguei Katkov <serguei.katkov@azul.com>2019-07-15 09:13:11 +0000
commitd021ad9fbeb6d29c8551879f703f45e263e7a700 (patch)
tree3e643470921aad90353013c1120f4e61a8d270c0 /llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp
parent1d554b7441258c8074c912c674f51b1b17625a38 (diff)
downloadbcm5719-llvm-d021ad9fbeb6d29c8551879f703f45e263e7a700.tar.gz
bcm5719-llvm-d021ad9fbeb6d29c8551879f703f45e263e7a700.zip
[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 llvm-svn: 366050
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp b/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp
index 6394d74f316..deb38df4420 100644
--- a/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnrollPeel.cpp
@@ -583,6 +583,18 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
SmallVector<std::pair<BasicBlock *, BasicBlock *>, 4> ExitEdges;
L->getExitEdges(ExitEdges);
+ DenseMap<BasicBlock *, BasicBlock *> ExitIDom;
+ if (DT) {
+ assert(L->hasDedicatedExits() && "No dedicated exits?");
+ for (auto Edge : ExitEdges) {
+ if (ExitIDom.count(Edge.second))
+ continue;
+ BasicBlock *BB = DT->getNode(Edge.second)->getIDom()->getBlock();
+ assert(L->contains(BB) && "IDom is not in a loop");
+ ExitIDom[Edge.second] = BB;
+ }
+ }
+
Function *F = Header->getParent();
// Set up all the necessary basic blocks. It is convenient to split the
@@ -675,9 +687,9 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
// latter is the first cloned loop body, as original PreHeader dominates
// the original loop body.
if (Iter == 0)
- for (auto Edge : ExitEdges)
- DT->changeImmediateDominator(Edge.second,
- cast<BasicBlock>(LVMap[Edge.first]));
+ for (auto Exit : ExitIDom)
+ DT->changeImmediateDominator(Exit.first,
+ cast<BasicBlock>(LVMap[Exit.second]));
#ifdef EXPENSIVE_CHECKS
assert(DT->verify(DominatorTree::VerificationLevel::Fast));
#endif
@@ -719,6 +731,9 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI,
// We modified the loop, update SE.
SE->forgetTopmostLoop(L);
+ // Finally DomtTree must be correct.
+ assert(DT->verify(DominatorTree::VerificationLevel::Fast));
+
// FIXME: Incrementally update loop-simplify
simplifyLoop(L, DT, LI, SE, AC, nullptr, PreserveLCSSA);
OpenPOWER on IntegriCloud