[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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232189 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjoy Das 2015-03-13 18:31:19 +00:00
parent 5a70dd1d82
commit 011536a1cc
2 changed files with 39 additions and 3 deletions

View 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.

View File

@ -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
}