aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2015-03-16 21:15:49 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2015-03-16 21:15:49 +0000
commit3905ad948eaa572f395f0130b3c4c0d119a128d1 (patch)
treef8c7954aad0554a6b9d09092db819ce3599bb3d8
parentdb03459c285096267183b569b8ffeba157c2a45d (diff)
downloadllvm-3905ad948eaa572f395f0130b3c4c0d119a128d1.tar.gz
Merge r232189 from trunk to 3.6
Original commit message: 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_36@232416 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp9
-rw-r--r--test/Analysis/ScalarEvolution/pr22856.ll33
2 files changed, 39 insertions, 3 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
index 59f19a002ec..7e9e35127a4 100644
--- a/lib/Analysis/ScalarEvolutionExpander.cpp
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -1776,9 +1776,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/test/Analysis/ScalarEvolution/pr22856.ll b/test/Analysis/ScalarEvolution/pr22856.ll
new file mode 100644
index 00000000000..89e83516efd
--- /dev/null
+++ b/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
+}