aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2016-06-18 04:38:31 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2016-06-18 04:38:31 +0000
commite8fd9561cb16d9d8398276e8c4ca836199b7699c (patch)
tree87338a5f276ac96b69740a92fa8c45a4d14dd75f /llvm/lib/Analysis/ScalarEvolution.cpp
parentdc62be191503c932a2025b2489c2da0c55d46ec3 (diff)
downloadllvm-e8fd9561cb16d9d8398276e8c4ca836199b7699c.zip
llvm-e8fd9561cb16d9d8398276e8c4ca836199b7699c.tar.gz
llvm-e8fd9561cb16d9d8398276e8c4ca836199b7699c.tar.bz2
[SCEV] Fix incorrect trip count computation
The way we elide max expressions when computing trip counts is incorrect -- it breaks cases like this: ``` static int wrapping_add(int a, int b) { return (int)((unsigned)a + (unsigned)b); } void test() { volatile int end_buf = 2147483548; // INT_MIN - 100 int end = end_buf; unsigned counter = 0; for (int start = wrapping_add(end, 200); start < end; start++) counter++; print(counter); } ``` Note: the `NoWrap` variable that was being tested has little to do with the values flowing into the max expression; it is a property of the induction variable. test/Transforms/LoopUnroll/nsw-tripcount.ll was added to solely test functionality I'm reverting in this change, so I've deleted the test fully. llvm-svn: 273079
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp28
1 files changed, 4 insertions, 24 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 2509031..c2e1825 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8668,18 +8668,8 @@ ScalarEvolution::howManyLessThans(const SCEV *LHS, const SCEV *RHS,
: ICmpInst::ICMP_ULT;
const SCEV *Start = IV->getStart();
const SCEV *End = RHS;
- if (!isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(Start, Stride), RHS)) {
- const SCEV *Diff = getMinusSCEV(RHS, Start);
- // If we have NoWrap set, then we can assume that the increment won't
- // overflow, in which case if RHS - Start is a constant, we don't need to
- // do a max operation since we can just figure it out statically
- if (NoWrap && isa<SCEVConstant>(Diff)) {
- if (cast<SCEVConstant>(Diff)->getAPInt().isNegative())
- End = Start;
- } else
- End = IsSigned ? getSMaxExpr(RHS, Start)
- : getUMaxExpr(RHS, Start);
- }
+ if (!isLoopEntryGuardedByCond(L, Cond, getMinusSCEV(Start, Stride), RHS))
+ End = IsSigned ? getSMaxExpr(RHS, Start) : getUMaxExpr(RHS, Start);
const SCEV *BECount = computeBECount(getMinusSCEV(End, Start), Stride, false);
@@ -8754,18 +8744,8 @@ ScalarEvolution::howManyGreaterThans(const SCEV *LHS, const SCEV *RHS,
const SCEV *Start = IV->getStart();
const SCEV *End = RHS;
- if (!isLoopEntryGuardedByCond(L, Cond, getAddExpr(Start, Stride), RHS)) {
- const SCEV *Diff = getMinusSCEV(RHS, Start);
- // If we have NoWrap set, then we can assume that the increment won't
- // overflow, in which case if RHS - Start is a constant, we don't need to
- // do a max operation since we can just figure it out statically
- if (NoWrap && isa<SCEVConstant>(Diff)) {
- if (!cast<SCEVConstant>(Diff)->getAPInt().isNegative())
- End = Start;
- } else
- End = IsSigned ? getSMinExpr(RHS, Start)
- : getUMinExpr(RHS, Start);
- }
+ if (!isLoopEntryGuardedByCond(L, Cond, getAddExpr(Start, Stride), RHS))
+ End = IsSigned ? getSMinExpr(RHS, Start) : getUMinExpr(RHS, Start);
const SCEV *BECount = computeBECount(getMinusSCEV(Start, End), Stride, false);