mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74376 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
553e571b43
commit
de53dc03f5
@ -70,6 +70,7 @@ namespace {
|
|||||||
IVUsers *IU;
|
IVUsers *IU;
|
||||||
LoopInfo *LI;
|
LoopInfo *LI;
|
||||||
ScalarEvolution *SE;
|
ScalarEvolution *SE;
|
||||||
|
DominatorTree *DT;
|
||||||
bool Changed;
|
bool Changed;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -329,6 +330,7 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||||||
IU = &getAnalysis<IVUsers>();
|
IU = &getAnalysis<IVUsers>();
|
||||||
LI = &getAnalysis<LoopInfo>();
|
LI = &getAnalysis<LoopInfo>();
|
||||||
SE = &getAnalysis<ScalarEvolution>();
|
SE = &getAnalysis<ScalarEvolution>();
|
||||||
|
DT = &getAnalysis<DominatorTree>();
|
||||||
Changed = false;
|
Changed = false;
|
||||||
|
|
||||||
// If there are any floating-point recurrences, attempt to
|
// 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))
|
if (!AR->isLoopInvariant(L) && !Stride->isLoopInvariant(L))
|
||||||
continue;
|
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;
|
Instruction *InsertPt = User;
|
||||||
if (PHINode *PHI = dyn_cast<PHINode>(InsertPt))
|
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) {
|
if (PHI->getIncomingValue(i) == Op) {
|
||||||
InsertPt = PHI->getIncomingBlock(i)->getTerminator();
|
if (InsertPt == User)
|
||||||
break;
|
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.
|
// Now expand it into actual Instructions and patch it into place.
|
||||||
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user