mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Fix SCEVExpander::visitAddRecExpr so that it remembers the induction variable
it inserted rather than using LoopInfo::getCanonicalInductionVariable to rediscover it, since that doesn't work on non-canonical loops. This fixes infinite recurrsion on such loops; PR7562. llvm-svn: 109419
This commit is contained in:
parent
52e662a7f7
commit
9e0ae022d2
@ -1112,21 +1112,13 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
|||||||
SE.getUnknown(expand(Rest))));
|
SE.getUnknown(expand(Rest))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// {0,+,1} --> Insert a canonical induction variable into the loop!
|
// If we don't yet have a canonical IV, create one.
|
||||||
if (S->isAffine() && S->getOperand(1)->isOne()) {
|
if (!CanonicalIV) {
|
||||||
// If there's a canonical IV, just use it.
|
|
||||||
if (CanonicalIV) {
|
|
||||||
assert(Ty == SE.getEffectiveSCEVType(CanonicalIV->getType()) &&
|
|
||||||
"IVs with types different from the canonical IV should "
|
|
||||||
"already have been handled!");
|
|
||||||
return CanonicalIV;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and insert the PHI node for the induction variable in the
|
// Create and insert the PHI node for the induction variable in the
|
||||||
// specified loop.
|
// specified loop.
|
||||||
BasicBlock *Header = L->getHeader();
|
BasicBlock *Header = L->getHeader();
|
||||||
PHINode *PN = PHINode::Create(Ty, "indvar", Header->begin());
|
CanonicalIV = PHINode::Create(Ty, "indvar", Header->begin());
|
||||||
rememberInstruction(PN);
|
rememberInstruction(CanonicalIV);
|
||||||
|
|
||||||
Constant *One = ConstantInt::get(Ty, 1);
|
Constant *One = ConstantInt::get(Ty, 1);
|
||||||
for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
|
for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header);
|
||||||
@ -1135,40 +1127,45 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
|||||||
if (L->contains(HP)) {
|
if (L->contains(HP)) {
|
||||||
// Insert a unit add instruction right before the terminator
|
// Insert a unit add instruction right before the terminator
|
||||||
// corresponding to the back-edge.
|
// corresponding to the back-edge.
|
||||||
Instruction *Add = BinaryOperator::CreateAdd(PN, One, "indvar.next",
|
Instruction *Add = BinaryOperator::CreateAdd(CanonicalIV, One,
|
||||||
|
"indvar.next",
|
||||||
HP->getTerminator());
|
HP->getTerminator());
|
||||||
rememberInstruction(Add);
|
rememberInstruction(Add);
|
||||||
PN->addIncoming(Add, HP);
|
CanonicalIV->addIncoming(Add, HP);
|
||||||
} else {
|
} else {
|
||||||
PN->addIncoming(Constant::getNullValue(Ty), HP);
|
CanonicalIV->addIncoming(Constant::getNullValue(Ty), HP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// {0,+,1} --> Insert a canonical induction variable into the loop!
|
||||||
|
if (S->isAffine() && S->getOperand(1)->isOne()) {
|
||||||
|
assert(Ty == SE.getEffectiveSCEVType(CanonicalIV->getType()) &&
|
||||||
|
"IVs with types different from the canonical IV should "
|
||||||
|
"already have been handled!");
|
||||||
|
return CanonicalIV;
|
||||||
|
}
|
||||||
|
|
||||||
// {0,+,F} --> {0,+,1} * F
|
// {0,+,F} --> {0,+,1} * F
|
||||||
// Get the canonical induction variable I for this loop.
|
|
||||||
Value *I = CanonicalIV ?
|
|
||||||
CanonicalIV :
|
|
||||||
getOrInsertCanonicalInductionVariable(L, Ty);
|
|
||||||
|
|
||||||
// If this is a simple linear addrec, emit it now as a special case.
|
// If this is a simple linear addrec, emit it now as a special case.
|
||||||
if (S->isAffine()) // {0,+,F} --> i*F
|
if (S->isAffine()) // {0,+,F} --> i*F
|
||||||
return
|
return
|
||||||
expand(SE.getTruncateOrNoop(
|
expand(SE.getTruncateOrNoop(
|
||||||
SE.getMulExpr(SE.getUnknown(I),
|
SE.getMulExpr(SE.getUnknown(CanonicalIV),
|
||||||
SE.getNoopOrAnyExtend(S->getOperand(1),
|
SE.getNoopOrAnyExtend(S->getOperand(1),
|
||||||
I->getType())),
|
CanonicalIV->getType())),
|
||||||
Ty));
|
Ty));
|
||||||
|
|
||||||
// If this is a chain of recurrences, turn it into a closed form, using the
|
// If this is a chain of recurrences, turn it into a closed form, using the
|
||||||
// folders, then expandCodeFor the closed form. This allows the folders to
|
// folders, then expandCodeFor the closed form. This allows the folders to
|
||||||
// simplify the expression without having to build a bunch of special code
|
// simplify the expression without having to build a bunch of special code
|
||||||
// into this folder.
|
// into this folder.
|
||||||
const SCEV *IH = SE.getUnknown(I); // Get I as a "symbolic" SCEV.
|
const SCEV *IH = SE.getUnknown(CanonicalIV); // Get I as a "symbolic" SCEV.
|
||||||
|
|
||||||
// Promote S up to the canonical IV type, if the cast is foldable.
|
// Promote S up to the canonical IV type, if the cast is foldable.
|
||||||
const SCEV *NewS = S;
|
const SCEV *NewS = S;
|
||||||
const SCEV *Ext = SE.getNoopOrAnyExtend(S, I->getType());
|
const SCEV *Ext = SE.getNoopOrAnyExtend(S, CanonicalIV->getType());
|
||||||
if (isa<SCEVAddRecExpr>(Ext))
|
if (isa<SCEVAddRecExpr>(Ext))
|
||||||
NewS = Ext;
|
NewS = Ext;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
; RUN: opt -indvars %s -disable-output
|
; RUN: opt -indvars %s -disable-output
|
||||||
|
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-n8:16:32:64"
|
||||||
|
|
||||||
declare i32 @putchar(i8) nounwind
|
declare i32 @putchar(i8) nounwind
|
||||||
|
|
||||||
@ -17,3 +18,38 @@ define void @t2(i1* %P) nounwind {
|
|||||||
; <label>:6 ; preds = %1
|
; <label>:6 ; preds = %1
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; PR7562
|
||||||
|
define void @fannkuch() nounwind {
|
||||||
|
entry: ; preds = %entry
|
||||||
|
br label %bb12
|
||||||
|
|
||||||
|
bb12: ; preds = %bb29, %entry
|
||||||
|
%i.1 = phi i32 [ undef, %entry ], [ %i.0, %bb29 ] ; <i32> [#uses=2]
|
||||||
|
%r.1 = phi i32 [ undef, %entry ], [ %r.0, %bb29 ] ; <i32> [#uses=2]
|
||||||
|
br i1 undef, label %bb13, label %bb24
|
||||||
|
|
||||||
|
bb13: ; preds = %bb12
|
||||||
|
br label %bb24
|
||||||
|
|
||||||
|
bb24: ; preds = %bb30, %bb13, %bb12
|
||||||
|
%i.2 = phi i32 [ %i.1, %bb13 ], [ %i.0, %bb30 ], [ %i.1, %bb12 ] ; <i32> [#uses=1]
|
||||||
|
%r.0 = phi i32 [ %r.1, %bb13 ], [ %2, %bb30 ], [ %r.1, %bb12 ] ; <i32> [#uses=3]
|
||||||
|
br label %bb28
|
||||||
|
|
||||||
|
bb27: ; preds = %bb28
|
||||||
|
%0 = add nsw i32 %i.0, 1 ; <i32> [#uses=1]
|
||||||
|
br label %bb28
|
||||||
|
|
||||||
|
bb28: ; preds = %bb27, %bb26
|
||||||
|
%i.0 = phi i32 [ %i.2, %bb24 ], [ %0, %bb27 ] ; <i32> [#uses=4]
|
||||||
|
%1 = icmp slt i32 %i.0, %r.0 ; <i1> [#uses=1]
|
||||||
|
br i1 %1, label %bb27, label %bb29
|
||||||
|
|
||||||
|
bb29: ; preds = %bb28
|
||||||
|
br i1 undef, label %bb12, label %bb30
|
||||||
|
|
||||||
|
bb30: ; preds = %bb29
|
||||||
|
%2 = add nsw i32 %r.0, 1 ; <i32> [#uses=1]
|
||||||
|
br label %bb24
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user