summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2018-04-24 10:33:08 +0000
committerChandler Carruth <chandlerc@gmail.com>2018-04-24 10:33:08 +0000
commit43acdb35bc94ed63b2ebd264aebfa2a757d5d545 (patch)
treed4945de8c4a756c8774fb5d1f271591e507c9e5d /llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
parente2bfcd6394e18e4cf04bc367758c4d667f43c97b (diff)
downloadbcm5719-llvm-43acdb35bc94ed63b2ebd264aebfa2a757d5d545.tar.gz
bcm5719-llvm-43acdb35bc94ed63b2ebd264aebfa2a757d5d545.zip
[PM/LoopUnswitch] Fix a bug in the loop block set formation of the new
loop unswitch. This code incorrectly added the header to the loop block set early. As a consequence we would incorrectly conclude that a nested loop body had already been visited when the header of the outer loop was the preheader of the nested loop. In retrospect, adding the header eagerly doesn't really make sense. It seems nicer to let the cycle be formed naturally. This will catch crazy bugs in the CFG reconstruction where we can't correctly form the cycle earlier rather than later, and makes the rest of the logic just fall out. I've also added various asserts that make these issues *much* easier to debug. llvm-svn: 330707
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
index c28311fe4b0..fed5e62157a 100644
--- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
+++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
@@ -1333,14 +1333,15 @@ static SmallPtrSet<const BasicBlock *, 16> recomputeLoopBlockSet(Loop &L,
if (LoopBlockSet.empty())
return LoopBlockSet;
- // Add the loop header to the set.
- LoopBlockSet.insert(Header);
-
// We found backedges, recurse through them to identify the loop blocks.
while (!Worklist.empty()) {
BasicBlock *BB = Worklist.pop_back_val();
assert(LoopBlockSet.count(BB) && "Didn't put block into the loop set!");
+ // No need to walk past the header.
+ if (BB == Header)
+ continue;
+
// Because we know the inner loop structure remains valid we can use the
// loop structure to jump immediately across the entire nested loop.
// Further, because it is in loop simplified form, we can directly jump
@@ -1388,6 +1389,8 @@ static SmallPtrSet<const BasicBlock *, 16> recomputeLoopBlockSet(Loop &L,
Worklist.push_back(Pred);
}
+ assert(LoopBlockSet.count(Header) && "Cannot fail to add the header!");
+
// We've found all the blocks participating in the loop, return our completed
// set.
return LoopBlockSet;
@@ -1792,9 +1795,12 @@ static bool unswitchInvariantBranch(
// unnecessary loops.
auto UpdateLCSSA = [&](Loop &UpdateL) {
#ifndef NDEBUG
- for (Loop *ChildL : UpdateL)
+ UpdateL.verifyLoop();
+ for (Loop *ChildL : UpdateL) {
+ ChildL->verifyLoop();
assert(ChildL->isRecursivelyLCSSAForm(DT, LI) &&
"Perturbed a child loop's LCSSA form!");
+ }
#endif
formLCSSA(UpdateL, DT, &LI, nullptr);
};
OpenPOWER on IntegriCloud