[llvm] r276077 - Revert "Revert r275883 and r275891. They seem to cause PR28608."
Michael Zolotukhin via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 19 18:55:27 PDT 2016
Author: mzolotukhin
Date: Tue Jul 19 20:55:27 2016
New Revision: 276077
URL: http://llvm.org/viewvc/llvm-project?rev=276077&view=rev
Log:
Revert "Revert r275883 and r275891. They seem to cause PR28608."
This reverts commit r276064, and thus reapplies r275891 and r275883 with
a fix for PR28608.
Added:
llvm/trunk/test/Transforms/LCSSA/pr28424.ll
llvm/trunk/test/Transforms/LCSSA/pr28608.ll
llvm/trunk/test/Transforms/LoopSimplify/pr28272.ll
Modified:
llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=276077&r1=276076&r2=276077&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Tue Jul 19 20:55:27 2016
@@ -64,6 +64,7 @@ bool llvm::formLCSSAForInstructions(Smal
DominatorTree &DT, LoopInfo &LI) {
SmallVector<Use *, 16> UsesToRewrite;
SmallVector<BasicBlock *, 8> ExitBlocks;
+ SmallSetVector<PHINode *, 16> PHIsToRemove;
PredIteratorCache PredCache;
bool Changed = false;
@@ -115,7 +116,8 @@ bool llvm::formLCSSAForInstructions(Smal
SmallVector<PHINode *, 16> AddedPHIs;
SmallVector<PHINode *, 8> PostProcessPHIs;
- SSAUpdater SSAUpdate;
+ SmallVector<PHINode *, 4> InsertedPHIs;
+ SSAUpdater SSAUpdate(&InsertedPHIs);
SSAUpdate.Initialize(I->getType(), I->getName());
// Insert the LCSSA phi's into all of the exit blocks dominated by the
@@ -184,6 +186,14 @@ bool llvm::formLCSSAForInstructions(Smal
// Otherwise, do full PHI insertion.
SSAUpdate.RewriteUse(*UseToRewrite);
+
+ // SSAUpdater might have inserted phi-nodes inside other loops. We'll need
+ // to post-process them to keep LCSSA form.
+ for (PHINode *InsertedPN : InsertedPHIs) {
+ if (auto *OtherLoop = LI.getLoopFor(InsertedPN->getParent()))
+ if (!L->contains(OtherLoop))
+ PostProcessPHIs.push_back(InsertedPN);
+ }
}
// Post process PHI instructions that were inserted into another disjoint
@@ -196,13 +206,19 @@ bool llvm::formLCSSAForInstructions(Smal
Worklist.push_back(PostProcessPN);
}
- // Remove PHI nodes that did not have any uses rewritten.
+ // Keep track of PHI nodes that we want to remove because they did not have
+ // any uses rewritten.
for (PHINode *PN : AddedPHIs)
if (PN->use_empty())
- PN->eraseFromParent();
+ PHIsToRemove.insert(PN);
Changed = true;
}
+ // Remove PHI nodes that did not have any uses rewritten.
+ for (PHINode *PN : PHIsToRemove) {
+ assert (PN->use_empty() && "Trying to remove a phi with uses.");
+ PN->eraseFromParent();
+ }
return Changed;
}
Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=276077&r1=276076&r2=276077&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Tue Jul 19 20:55:27 2016
@@ -327,6 +327,8 @@ static Loop *separateNestedLoop(Loop *L,
else
NewOuter->addChildLoop(L->removeChildLoop(SubLoops.begin() + I));
+ SmallVector<BasicBlock *, 8> OuterLoopBlocks;
+ OuterLoopBlocks.push_back(NewBB);
// Now that we know which blocks are in L and which need to be moved to
// OuterLoop, move any blocks that need it.
for (unsigned i = 0; i != L->getBlocks().size(); ++i) {
@@ -334,12 +336,53 @@ static Loop *separateNestedLoop(Loop *L,
if (!BlocksInL.count(BB)) {
// Move this block to the parent, updating the exit blocks sets
L->removeBlockFromLoop(BB);
- if ((*LI)[BB] == L)
+ if ((*LI)[BB] == L) {
LI->changeLoopFor(BB, NewOuter);
+ OuterLoopBlocks.push_back(BB);
+ }
--i;
}
}
+ // Split edges to exit blocks from the inner loop, if they emerged in the
+ // process of separating the outer one.
+ SmallVector<BasicBlock *, 8> ExitBlocks;
+ L->getExitBlocks(ExitBlocks);
+ SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
+ ExitBlocks.end());
+ for (BasicBlock *ExitBlock : ExitBlockSet) {
+ if (any_of(predecessors(ExitBlock),
+ [L](BasicBlock *BB) { return !L->contains(BB); })) {
+ rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA);
+ }
+ }
+
+ if (PreserveLCSSA) {
+ // 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.
+
+ // 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);
+ }
+ }
+ }
+ SmallVector<Instruction *, 8> Worklist(WorklistSet.begin(),
+ WorklistSet.end());
+ formLCSSAForInstructions(Worklist, *DT, *LI);
+ assert(NewOuter->isRecursivelyLCSSAForm(*DT) &&
+ "LCSSA is broken after separating nested loops!");
+ }
+
return NewOuter;
}
@@ -541,17 +584,12 @@ ReprocessLoop:
SmallSetVector<BasicBlock *, 8> ExitBlockSet(ExitBlocks.begin(),
ExitBlocks.end());
for (BasicBlock *ExitBlock : ExitBlockSet) {
- for (pred_iterator PI = pred_begin(ExitBlock), PE = pred_end(ExitBlock);
- PI != PE; ++PI)
- // Must be exactly this loop: no subloops, parent loops, or non-loop preds
- // allowed.
- if (!L->contains(*PI)) {
- if (rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA)) {
- ++NumInserted;
- Changed = true;
- }
- break;
- }
+ if (any_of(predecessors(ExitBlock),
+ [L](BasicBlock *BB) { return !L->contains(BB); })) {
+ rewriteLoopExitBlock(L, ExitBlock, DT, LI, PreserveLCSSA);
+ ++NumInserted;
+ Changed = true;
+ }
}
// If the header has more than two predecessors at this point (from the
Added: llvm/trunk/test/Transforms/LCSSA/pr28424.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LCSSA/pr28424.ll?rev=276077&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LCSSA/pr28424.ll (added)
+++ llvm/trunk/test/Transforms/LCSSA/pr28424.ll Tue Jul 19 20:55:27 2016
@@ -0,0 +1,87 @@
+; RUN: opt < %s -lcssa -S -o - | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+
+; PR28424
+; Here LCSSA adds phi-nodes for %x into the loop exits. Then, SSAUpdater needs
+; to insert phi-nodes to merge these values. That creates a new def, which in
+; its turn needs another LCCSA phi-node, and this test ensures that we insert
+; it.
+
+; CHECK-LABEL: @foo1
+define internal i32 @foo1() {
+entry:
+ br label %header
+
+header:
+ %x = add i32 0, 1
+ br i1 undef, label %if, label %loopexit1
+
+if:
+ br i1 undef, label %latch, label %loopexit2
+
+latch:
+ br i1 undef, label %header, label %loopexit3
+
+; CHECK: loopexit1:
+; CHECK: %x.lcssa = phi i32 [ %x, %header ]
+loopexit1:
+ br label %loop_with_insert_point
+
+; CHECK: loopexit2:
+; CHECK: %x.lcssa1 = phi i32 [ %x, %if ]
+loopexit2:
+ br label %exit
+
+; CHECK: loopexit3:
+; CHECK: %x.lcssa2 = phi i32 [ %x, %latch ]
+loopexit3:
+ br label %loop_with_insert_point
+
+; CHECK: loop_with_insert_point:
+; CHECK: %x4 = phi i32 [ %x4, %loop_with_insert_point ], [ %x.lcssa2, %loopexit3 ], [ %x.lcssa, %loopexit1 ]
+loop_with_insert_point:
+ br i1 undef, label %loop_with_insert_point, label %bb
+
+; CHECK: bb:
+; CHECK: %x4.lcssa = phi i32 [ %x4, %loop_with_insert_point ]
+bb:
+ br label %exit
+
+; CHECK: exit:
+; CHECK: %x3 = phi i32 [ %x4.lcssa, %bb ], [ %x.lcssa1, %loopexit2 ]
+exit:
+ ret i32 %x
+}
+
+; CHECK-LABEL: @foo2
+define internal i32 @foo2() {
+entry:
+ br label %header
+
+header:
+ %x = add i32 0, 1
+ br i1 undef, label %latch, label %loopexit1
+
+latch:
+ br i1 undef, label %header, label %loopexit2
+
+; CHECK: loopexit1:
+; CHECK: %x.lcssa = phi i32 [ %x, %header ]
+loopexit1:
+ br label %loop_with_insert_point
+
+; CHECK: loopexit2:
+; CHECK: %x.lcssa1 = phi i32 [ %x, %latch ]
+loopexit2:
+ br label %loop_with_insert_point
+
+; CHECK: loop_with_insert_point:
+; CHECK: %x2 = phi i32 [ %x2, %loop_with_insert_point ], [ %x.lcssa1, %loopexit2 ], [ %x.lcssa, %loopexit1 ]
+loop_with_insert_point:
+ br i1 undef, label %loop_with_insert_point, label %exit
+
+; CHECK: exit:
+; CHECK: %x2.lcssa = phi i32 [ %x2, %loop_with_insert_point ]
+exit:
+ ret i32 %x
+}
Added: llvm/trunk/test/Transforms/LCSSA/pr28608.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LCSSA/pr28608.ll?rev=276077&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LCSSA/pr28608.ll (added)
+++ llvm/trunk/test/Transforms/LCSSA/pr28608.ll Tue Jul 19 20:55:27 2016
@@ -0,0 +1,35 @@
+; RUN: opt < %s -lcssa -disable-output
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; PR28608
+; Check that we don't crash on this test.
+
+define void @foo() {
+entry:
+ br label %bb1
+
+bb1:
+ br label %bb2
+
+bb2:
+ %x = phi i32 [ undef, %bb5 ], [ undef, %bb1 ]
+ br i1 undef, label %bb3, label %bb6
+
+bb3:
+ br i1 undef, label %bb5, label %bb4
+
+bb4:
+ br label %bb6
+
+bb5:
+ br label %bb2
+
+bb6:
+ br label %bb1
+
+exit:
+ %y = add i32 0, %x
+ ret void
+}
+
Added: llvm/trunk/test/Transforms/LoopSimplify/pr28272.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopSimplify/pr28272.ll?rev=276077&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopSimplify/pr28272.ll (added)
+++ llvm/trunk/test/Transforms/LoopSimplify/pr28272.ll Tue Jul 19 20:55:27 2016
@@ -0,0 +1,76 @@
+; RUN: opt < %s -lcssa -loop-unroll -S | FileCheck %s
+target triple = "x86_64-unknown-linux-gnu"
+
+; PR28272
+; When LoopSimplify separates nested loops, it might break LCSSA form: values
+; from the original loop might be used in the outer loop. This test invokes
+; loop-unroll, which calls loop-simplify before itself. If LCSSA is broken
+; after loop-simplify, we crash on assertion.
+
+; CHECK-LABEL: @foo
+define void @foo() {
+entry:
+ br label %header
+
+header:
+ br label %loop1
+
+loop1:
+ br i1 true, label %loop1, label %bb43
+
+bb43:
+ %a = phi i32 [ undef, %loop1 ], [ 0, %bb45 ], [ %a, %bb54 ]
+ %b = phi i32 [ 0, %loop1 ], [ 1, %bb54 ], [ %c, %bb45 ]
+ br i1 true, label %bb114, label %header
+
+bb114:
+ %c = add i32 0, 1
+ %d = add i32 0, 1
+ br i1 true, label %bb45, label %bb54
+
+bb45:
+ %x = add i32 %d, 0
+ br label %bb43
+
+bb54:
+ br label %bb43
+}
+
+; CHECK-LABEL: @foo2
+define void @foo2() {
+entry:
+ br label %outer
+
+outer.loopexit:
+ br label %outer
+
+outer:
+ br label %loop1
+
+loop1:
+ br i1 true, label %loop1, label %loop2.preheader
+
+loop2.preheader:
+ %a.ph = phi i32 [ undef, %loop1 ]
+ %b.ph = phi i32 [ 0, %loop1 ]
+ br label %loop2
+
+loop2:
+ %a = phi i32 [ 0, %loop2.if.true ], [ %a, %loop2.if.false ], [ %a.ph, %loop2.preheader ], [0, %bb]
+ %b = phi i32 [ 1, %loop2.if.false ], [ %c, %loop2.if.true ], [ %b.ph, %loop2.preheader ], [%c, %bb]
+ br i1 true, label %loop2.if, label %outer.loopexit
+
+loop2.if:
+ %c = add i32 0, 1
+ switch i32 undef, label %loop2.if.false [i32 0, label %loop2.if.true
+ i32 1, label %bb]
+
+loop2.if.true:
+ br i1 undef, label %loop2, label %bb
+
+loop2.if.false:
+ br label %loop2
+
+bb:
+ br label %loop2
+}
More information about the llvm-commits
mailing list