Fix ScalarEvolution::getAddRecExpr's code which canonicalized the

nesting order of nested AddRec expressions to skip the transformation
if it would introduce an AddRec with operands not loop-invariant
with respect to its loop.

llvm-svn: 74343
This commit is contained in:
Dan Gohman 2009-06-26 22:36:20 +00:00
parent 2d83134ca6
commit cc030b7e51
1 changed files with 23 additions and 2 deletions

View File

@ -1651,8 +1651,29 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV*> &Operands,
SmallVector<const SCEV*, 4> NestedOperands(NestedAR->op_begin(),
NestedAR->op_end());
Operands[0] = NestedAR->getStart();
NestedOperands[0] = getAddRecExpr(Operands, L);
return getAddRecExpr(NestedOperands, NestedLoop);
// AddRecs require their operands be loop-invariant with respect to their
// loops. Don't perform this transformation if it would break this
// requirement.
bool AllInvariant = true;
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
if (!Operands[i]->isLoopInvariant(L)) {
AllInvariant = false;
break;
}
if (AllInvariant) {
NestedOperands[0] = getAddRecExpr(Operands, L);
AllInvariant = true;
for (unsigned i = 0, e = NestedOperands.size(); i != e; ++i)
if (!NestedOperands[i]->isLoopInvariant(NestedLoop)) {
AllInvariant = false;
break;
}
if (AllInvariant)
// Ok, both add recurrences are valid after the transformation.
return getAddRecExpr(NestedOperands, NestedLoop);
}
// Reset Operands to its original state.
Operands[0] = NestedAR;
}
}