diff options
author | Andrew Trick <atrick@apple.com> | 2011-09-28 17:02:54 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2011-09-28 17:02:54 +0000 |
commit | ef8e4efff8f247a0dd216e9485d321c612dac760 (patch) | |
tree | 9658e272cdafc01ab9f68aa6ab2874d4c7f45139 /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | d7aac28ae97d6a5f67ba1457c1b78568ff8ba96f (diff) | |
download | bcm5719-llvm-ef8e4efff8f247a0dd216e9485d321c612dac760.tar.gz bcm5719-llvm-ef8e4efff8f247a0dd216e9485d321c612dac760.zip |
indvars: generalize SCEV getPreStartForSignExtend.
Handle general Add expressions to avoid leaving around redundant
32-bit IVs.
llvm-svn: 140701
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index b1662a02608..ea45e9d72c7 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1070,14 +1070,26 @@ static const SCEV *getPreStartForSignExtend(const SCEVAddRecExpr *AR, // Check for a simple looking step prior to loop entry. const SCEVAddExpr *SA = dyn_cast<SCEVAddExpr>(Start); - if (!SA || SA->getNumOperands() != 2 || SA->getOperand(0) != Step) + if (!SA) + return 0; + + // Create an AddExpr for "PreStart" after subtracting Step. Full SCEV + // subtraction is expensive. For this purpose, perform a quick and dirty + // difference, by checking for Step in the operand list. + SmallVector<const SCEV *, 4> DiffOps; + for (SCEVAddExpr::op_iterator I = SA->op_begin(), E = SA->op_end(); + I != E; ++I) { + if (*I != Step) + DiffOps.push_back(*I); + } + if (DiffOps.size() == SA->getNumOperands()) return 0; // This is a postinc AR. Check for overflow on the preinc recurrence using the // same three conditions that getSignExtendedExpr checks. // 1. NSW flags on the step increment. - const SCEV *PreStart = SA->getOperand(1); + const SCEV *PreStart = SE->getAddExpr(DiffOps, SA->getNoWrapFlags()); const SCEVAddRecExpr *PreAR = dyn_cast<SCEVAddRecExpr>( SE->getAddRecExpr(PreStart, Step, L, SCEV::FlagAnyWrap)); |