summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2011-09-28 17:02:54 +0000
committerAndrew Trick <atrick@apple.com>2011-09-28 17:02:54 +0000
commitf63ae2159d2c20ea239e4c6d4e74bd2f14ebd408 (patch)
tree4900225107d73763e0f5d11b1b8e0839174a64cf /lib
parented0e4c85c4c022ca593d5651b88ddfbc86730ba6 (diff)
downloadllvm-f63ae2159d2c20ea239e4c6d4e74bd2f14ebd408.tar.gz
llvm-f63ae2159d2c20ea239e4c6d4e74bd2f14ebd408.tar.bz2
llvm-f63ae2159d2c20ea239e4c6d4e74bd2f14ebd408.tar.xz
indvars: generalize SCEV getPreStartForSignExtend.
Handle general Add expressions to avoid leaving around redundant 32-bit IVs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140701 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index b1662a0260..ea45e9d72c 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/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));