mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-29 22:50:55 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109419 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7da5d3fc65
commit
6ebfd72f37
@ -1112,21 +1112,13 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||
SE.getUnknown(expand(Rest))));
|
||||
}
|
||||
|
||||
// {0,+,1} --> Insert a canonical induction variable into the loop!
|
||||
if (S->isAffine() && S->getOperand(1)->isOne()) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// If we don't yet have a canonical IV, create one.
|
||||
if (!CanonicalIV) {
|
||||
// Create and insert the PHI node for the induction variable in the
|
||||
// specified loop.
|
||||
BasicBlock *Header = L->getHeader();
|
||||
PHINode *PN = PHINode::Create(Ty, "indvar", Header->begin());
|
||||
rememberInstruction(PN);
|
||||
CanonicalIV = PHINode::Create(Ty, "indvar", Header->begin());
|
||||
rememberInstruction(CanonicalIV);
|
||||
|
||||
Constant *One = ConstantInt::get(Ty, 1);
|
||||
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)) {
|
||||
// Insert a unit add instruction right before the terminator
|
||||
// corresponding to the back-edge.
|
||||
Instruction *Add = BinaryOperator::CreateAdd(PN, One, "indvar.next",
|
||||
HP->getTerminator());
|
||||
Instruction *Add = BinaryOperator::CreateAdd(CanonicalIV, One,
|
||||
"indvar.next",
|
||||
HP->getTerminator());
|
||||
rememberInstruction(Add);
|
||||
PN->addIncoming(Add, HP);
|
||||
CanonicalIV->addIncoming(Add, HP);
|
||||
} 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
|
||||
// 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 (S->isAffine()) // {0,+,F} --> i*F
|
||||
return
|
||||
expand(SE.getTruncateOrNoop(
|
||||
SE.getMulExpr(SE.getUnknown(I),
|
||||
SE.getMulExpr(SE.getUnknown(CanonicalIV),
|
||||
SE.getNoopOrAnyExtend(S->getOperand(1),
|
||||
I->getType())),
|
||||
CanonicalIV->getType())),
|
||||
Ty));
|
||||
|
||||
// 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
|
||||
// simplify the expression without having to build a bunch of special code
|
||||
// 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.
|
||||
const SCEV *NewS = S;
|
||||
const SCEV *Ext = SE.getNoopOrAnyExtend(S, I->getType());
|
||||
const SCEV *Ext = SE.getNoopOrAnyExtend(S, CanonicalIV->getType());
|
||||
if (isa<SCEVAddRecExpr>(Ext))
|
||||
NewS = Ext;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
; 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
|
||||
|
||||
@ -17,3 +18,38 @@ define void @t2(i1* %P) nounwind {
|
||||
; <label>:6 ; preds = %1
|
||||
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