forked from OSchip/llvm-project
[LoopSimplify] Rebuild LCSSA for the inner loop after separating nested loops.
Summary: This hopefully fixes PR28825. The problem now was that a value from the original loop was used in a subloop, which became a sibling after separation. While a subloop doesn't need an lcssa phi node, a sibling does, and that's where we broke LCSSA. The most natural way to fix this now is to simply call formLCSSA on the original loop: it'll do what we've been doing before plus it'll cover situations described above. I think we don't need to run formLCSSARecursively here, and we have an assert to verify this (I've tried testing it on LLVM testsuite + SPECs). I'd be happy to be corrected here though. I also changed a run line in the test from '-lcssa -loop-unroll' to '-lcssa -loop-simplify -indvars', because it exercises LCSSA preservation to the same extent, but also makes less unrelated transformation on the CFG, which makes it easier to verify. Reviewers: chandlerc, sanjoy, silvas Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D23288 llvm-svn: 278173
This commit is contained in:
parent
3c05edfd5e
commit
aae168f993
|
@ -361,39 +361,11 @@ static Loop *separateNestedLoop(Loop *L, BasicBlock *Preheader,
|
|||
// Fix LCSSA form for L. Some values, which previously were only used inside
|
||||
// L, can now be used in NewOuter loop. We need to insert phi-nodes for them
|
||||
// in corresponding exit blocks.
|
||||
// We don't need to form LCSSA recursively, because there cannot be uses
|
||||
// inside a newly created loop of defs from inner loops as those would
|
||||
// already be a use of an LCSSA phi node.
|
||||
formLCSSA(*L, *DT, LI, SE);
|
||||
|
||||
// Go through all instructions in OuterLoopBlocks and check if they are
|
||||
// using operands from the inner loop. In this case we'll need to fix LCSSA
|
||||
// for these instructions.
|
||||
SmallSetVector<Instruction *, 8> WorklistSet;
|
||||
for (BasicBlock *OuterBB: OuterLoopBlocks) {
|
||||
for (Instruction &I : *OuterBB) {
|
||||
for (Value *Op : I.operands()) {
|
||||
Instruction *OpI = dyn_cast<Instruction>(Op);
|
||||
if (!OpI || !L->contains(OpI))
|
||||
continue;
|
||||
WorklistSet.insert(OpI);
|
||||
}
|
||||
}
|
||||
}
|
||||
// We also need to check exit blocks of the outer loop - it might be using
|
||||
// values from what now became an inner loop.
|
||||
SmallVector<BasicBlock*, 8> ExitBlocks;
|
||||
NewOuter->getExitBlocks(ExitBlocks);
|
||||
for (BasicBlock *ExitBB: ExitBlocks) {
|
||||
for (Instruction &I : *ExitBB) {
|
||||
for (Value *Op : I.operands()) {
|
||||
Instruction *OpI = dyn_cast<Instruction>(Op);
|
||||
if (!OpI || !L->contains(OpI))
|
||||
continue;
|
||||
WorklistSet.insert(OpI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SmallVector<Instruction *, 8> Worklist(WorklistSet.begin(),
|
||||
WorklistSet.end());
|
||||
formLCSSAForInstructions(Worklist, *DT, *LI);
|
||||
assert(NewOuter->isRecursivelyLCSSAForm(*DT) &&
|
||||
"LCSSA is broken after separating nested loops!");
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: opt < %s -lcssa -loop-unroll -S | FileCheck %s
|
||||
; RUN: opt < %s -lcssa -loop-simplify -indvars -S | FileCheck %s
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; PR28272, PR28825
|
||||
|
@ -106,3 +106,34 @@ bb_end:
|
|||
%x = getelementptr i32, i32* %b
|
||||
br label %bb_end
|
||||
}
|
||||
|
||||
; When LoopSimplify separates nested loops, it might break LCSSA form: values
|
||||
; from the original loop might occur in a loop, which is now a sibling of the
|
||||
; original loop (before separating it was a subloop of the original loop, and
|
||||
; thus didn't require an lcssa phi nodes).
|
||||
; CHECK-LABEL: @foo4
|
||||
define void @foo4() {
|
||||
bb1:
|
||||
br label %bb2
|
||||
|
||||
; CHECK: bb2.loopexit:
|
||||
bb2.loopexit: ; preds = %bb3
|
||||
%i.ph = phi i32 [ 0, %bb3 ]
|
||||
br label %bb2
|
||||
|
||||
; CHECK: bb2.outer:
|
||||
; CHECK: bb2:
|
||||
bb2: ; preds = %bb2.loopexit, %bb2, %bb1
|
||||
%i = phi i32 [ 0, %bb1 ], [ %i, %bb2 ], [ %i.ph, %bb2.loopexit ]
|
||||
%x = load i32, i32* undef, align 8
|
||||
br i1 undef, label %bb2, label %bb3.preheader
|
||||
|
||||
; CHECK: bb3.preheader:
|
||||
bb3.preheader: ; preds = %bb2
|
||||
; CHECK: %x.lcssa = phi i32 [ %x, %bb2 ]
|
||||
br label %bb3
|
||||
|
||||
bb3: ; preds = %bb3.preheader, %bb3
|
||||
%y = add i32 2, %x
|
||||
br i1 true, label %bb2.loopexit, label %bb3
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue