summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-01-09 22:58:47 +0000
committerChris Lattner <sabre@nondot.org>2011-01-09 22:58:47 +0000
commit28f140a33e61c3bc197bed5279f5d3a975a273a3 (patch)
treefefe7b17d07974c58775d260ccc6c03109ec2ffe /llvm/lib/Analysis/ScalarEvolution.cpp
parent8828e482b6ddbe1b96f0a287f9002b42b876f700 (diff)
downloadbcm5719-llvm-28f140a33e61c3bc197bed5279f5d3a975a273a3.tar.gz
bcm5719-llvm-28f140a33e61c3bc197bed5279f5d3a975a273a3.zip
Step #4 in improving trip count analysis: HowFarToZero can analyze
NUW AddRec's much more aggressively. We now get a trip count for @test2 in nsw.ll llvm-svn: 123138
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index cfaacd76309..0c16bbc334c 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -4821,8 +4821,9 @@ ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
#endif
// Pick the smallest positive root value.
if (ConstantInt *CB =
- dyn_cast<ConstantInt>(ConstantExpr::getICmp(ICmpInst::ICMP_ULT,
- R1->getValue(), R2->getValue()))) {
+ dyn_cast<ConstantInt>(ConstantExpr::getICmp(CmpInst::ICMP_ULT,
+ R1->getValue(),
+ R2->getValue()))) {
if (CB->getZExtValue() == false)
std::swap(R1, R2); // R1 is the minimum root now.
@@ -4856,6 +4857,14 @@ ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) {
const SCEV *Start = getSCEVAtScope(AddRec->getStart(), L->getParentLoop());
const SCEV *Step = getSCEVAtScope(AddRec->getOperand(1), L->getParentLoop());
+ // If the AddRec is NUW, then (in an unsigned sense) it cannot be counting up
+ // to wrap to 0, it must be counting down to equal 0. Also, while counting
+ // down, it cannot "miss" 0 (which would cause it to wrap), regardless of what
+ // the stride is. As such, NUW addrec's will always become zero in
+ // "start / -stride" steps, and we know that the division is exact.
+ if (AddRec->hasNoUnsignedWrap())
+ return getUDivExpr(Start, getNegativeSCEV(Step));
+
// For now we handle only constant steps.
const SCEVConstant *StepC = dyn_cast<SCEVConstant>(Step);
if (StepC == 0)
OpenPOWER on IntegriCloud