summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-03-13 18:31:19 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-03-13 18:31:19 +0000
commitf1e9e1df2574836ae9ae28af4f3c1d54bd0e7b3a (patch)
tree3a68a3a3186b841518d8ee03c0ecfc93ca3ba887
parentba3e5ecf075c1d186906c06fe4f85a560c244699 (diff)
downloadbcm5719-llvm-f1e9e1df2574836ae9ae28af4f3c1d54bd0e7b3a.tar.gz
bcm5719-llvm-f1e9e1df2574836ae9ae28af4f3c1d54bd0e7b3a.zip
[SCEV] Fix PR22856.
Summary: ScalarEvolutionExpander assumes that the header block of a loop is a legal place to have a use for a phi node. This is true only for phis that are either in the header or dominate the header block, but it is not true for phi nodes that are strictly internal to the loop body. This change teaches ScalarEvolutionExpander to place uses of PHI nodes in the basic block the PHI nodes belong to. This is always legal, and `hoistIVInc` ensures that the said position dominates `IsomorphicInc`. Reviewers: atrick Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8311 llvm-svn: 232189
-rw-r--r--llvm/lib/Analysis/ScalarEvolutionExpander.cpp9
-rw-r--r--llvm/test/Analysis/ScalarEvolution/pr22856.ll33
2 files changed, 39 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
index a7ec937e5bc..063e29e26f5 100644
--- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -1771,9 +1771,12 @@ unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
<< *IsomorphicInc << '\n');
Value *NewInc = OrigInc;
if (OrigInc->getType() != IsomorphicInc->getType()) {
- Instruction *IP = isa<PHINode>(OrigInc)
- ? (Instruction*)L->getHeader()->getFirstInsertionPt()
- : OrigInc->getNextNode();
+ Instruction *IP = nullptr;
+ if (PHINode *PN = dyn_cast<PHINode>(OrigInc))
+ IP = PN->getParent()->getFirstInsertionPt();
+ else
+ IP = OrigInc->getNextNode();
+
IRBuilder<> Builder(IP);
Builder.SetCurrentDebugLocation(IsomorphicInc->getDebugLoc());
NewInc = Builder.
diff --git a/llvm/test/Analysis/ScalarEvolution/pr22856.ll b/llvm/test/Analysis/ScalarEvolution/pr22856.ll
new file mode 100644
index 00000000000..89e83516efd
--- /dev/null
+++ b/llvm/test/Analysis/ScalarEvolution/pr22856.ll
@@ -0,0 +1,33 @@
+; RUN: opt -loop-reduce -verify < %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64--linux-gnu"
+
+define void @unbounded() {
+
+block_A:
+ %0 = sext i32 undef to i64
+ br i1 undef, label %block_F, label %block_G
+
+block_C: ; preds = %block_F
+ br i1 undef, label %block_D, label %block_E
+
+block_D: ; preds = %block_D, %block_C
+ br i1 undef, label %block_E, label %block_D
+
+block_E: ; preds = %block_D, %block_C
+ %iv2 = phi i64 [ %4, %block_D ], [ %4, %block_C ]
+ %1 = add nsw i32 %iv1, 1
+ %2 = icmp eq i32 %1, undef
+ br i1 %2, label %block_G, label %block_F
+
+block_F: ; preds = %block_E, %block_A
+ %iv3 = phi i64 [ %iv2, %block_E ], [ %0, %block_A ]
+ %iv1 = phi i32 [ %1, %block_E ], [ undef, %block_A ]
+ %3 = add nsw i64 %iv3, 2
+ %4 = add nsw i64 %iv3, 1
+ br label %block_C
+
+block_G: ; preds = %block_E, %block_A
+ ret void
+}
OpenPOWER on IntegriCloud