1
0
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:
Dan Gohman 2010-07-26 18:28:14 +00:00
parent 52e662a7f7
commit 9e0ae022d2
2 changed files with 57 additions and 24 deletions

View File

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

View File

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