diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2018-04-24 10:33:08 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2018-04-24 10:33:08 +0000 |
commit | 43acdb35bc94ed63b2ebd264aebfa2a757d5d545 (patch) | |
tree | d4945de8c4a756c8774fb5d1f271591e507c9e5d /llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp | |
parent | e2bfcd6394e18e4cf04bc367758c4d667f43c97b (diff) | |
download | bcm5719-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.cpp | 14 |
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); }; |