When a value is used multiple times within a single PHI, instructions

inserted to replace that value must dominate all of of the basic
blocks associated with the uses of the value in the PHI, not just
one of them.

llvm-svn: 74376
This commit is contained in:
Dan Gohman 2009-06-27 05:16:57 +00:00
parent d17366ae72
commit fe174b6952
2 changed files with 48 additions and 3 deletions

View File

@ -70,6 +70,7 @@ namespace {
IVUsers *IU;
LoopInfo *LI;
ScalarEvolution *SE;
DominatorTree *DT;
bool Changed;
public:
@ -329,6 +330,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
IU = &getAnalysis<IVUsers>();
LI = &getAnalysis<LoopInfo>();
SE = &getAnalysis<ScalarEvolution>();
DT = &getAnalysis<DominatorTree>();
Changed = false;
// If there are any floating-point recurrences, attempt to
@ -479,12 +481,22 @@ void IndVarSimplify::RewriteIVExpressions(Loop *L, const Type *LargestType,
if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
continue;
// Determine the insertion point for this user. By default, insert
// immediately before the user. The SCEVExpander class will automatically
// hoist loop invariants out of the loop. For PHI nodes, there may be
// multiple uses, so compute the nearest common dominator for the
// incoming blocks.
Instruction *InsertPt = User;
if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
for (unsigned i = 0; ; ++i)
for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
if (PHI->getIncomingValue(i) == Op) {
InsertPt = PHI->getIncomingBlock(i)->getTerminator();
break;
if (InsertPt == User)
InsertPt = PHI->getIncomingBlock(i)->getTerminator();
else
InsertPt =
DT->findNearestCommonDominator(InsertPt->getParent(),
PHI->getIncomingBlock(i))
->getTerminator();
}
// Now expand it into actual Instructions and patch it into place.

View File

@ -0,0 +1,33 @@
; RUN: llvm-as < %s | opt -indvars
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
@ue = external global i64
define i32 @foo() nounwind {
entry:
br label %bb38.i
bb14.i27:
%t0 = load i64* @ue, align 8
%t1 = sub i64 %t0, %i.0.i35
%t2 = add i64 %t1, 1
br i1 undef, label %bb15.i28, label %bb19.i31
bb15.i28:
br label %bb19.i31
bb19.i31:
%y.0.i = phi i64 [ %t2, %bb15.i28 ], [ %t2, %bb14.i27 ]
br label %bb35.i
bb35.i:
br i1 undef, label %bb37.i, label %bb14.i27
bb37.i:
%t3 = add i64 %i.0.i35, 1
br label %bb38.i
bb38.i:
%i.0.i35 = phi i64 [ 1, %entry ], [ %t3, %bb37.i ]
br label %bb35.i
}