[SCEV] Fix PR22856.
authorSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 13 Mar 2015 18:31:19 +0000 (18:31 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 13 Mar 2015 18:31:19 +0000 (18:31 +0000)
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/trunk@232189 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ScalarEvolutionExpander.cpp
test/Analysis/ScalarEvolution/pr22856.ll [new file with mode: 0644]

index a7ec937e5bcae56ad2f7c35627b46cdb2dce3c2c..063e29e26f504064e9a630d606a201ee431f7214 100644 (file)
@@ -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/test/Analysis/ScalarEvolution/pr22856.ll b/test/Analysis/ScalarEvolution/pr22856.ll
new file mode 100644 (file)
index 0000000..89e8351
--- /dev/null
@@ -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
+}