summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorZheng Chen <czhengsz@cn.ibm.com>2020-01-10 22:50:39 -0500
committerZheng Chen <czhengsz@cn.ibm.com>2020-01-11 23:26:35 -0500
commit569ccfc384a5434c35c09adba8c44c46014297e6 (patch)
tree69d40519c37868f045dadeb6c536783c7c7a592a /llvm/lib/Analysis/ScalarEvolution.cpp
parentefb674ac2f2b0f06adc3f00df3134dadf1c875df (diff)
downloadbcm5719-llvm-569ccfc384a5434c35c09adba8c44c46014297e6.tar.gz
bcm5719-llvm-569ccfc384a5434c35c09adba8c44c46014297e6.zip
[SCEV] more accurate range for addrecexpr with nsw flag.
Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D72436
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 7d5c71eafed..f8d23c40e0c 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5678,23 +5678,31 @@ ScalarEvolution::getRangeRef(const SCEV *S,
ConservativeResult = ConservativeResult.intersectWith(
ConstantRange(C->getAPInt(), APInt(BitWidth, 0)), RangeType);
- // If there's no signed wrap, and all the operands have the same sign or
- // zero, the value won't ever change sign.
+ // If there's no signed wrap, and all the operands except initial value have
+ // the same sign or zero, the value won't ever be:
+ // 1: smaller than initial value if operands are non negative,
+ // 2: bigger than initial value if operands are non positive.
+ // For both cases, value can not cross signed min/max boundary.
if (AddRec->hasNoSignedWrap()) {
bool AllNonNeg = true;
bool AllNonPos = true;
- for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) {
- if (!isKnownNonNegative(AddRec->getOperand(i))) AllNonNeg = false;
- if (!isKnownNonPositive(AddRec->getOperand(i))) AllNonPos = false;
+ for (unsigned i = 1, e = AddRec->getNumOperands(); i != e; ++i) {
+ if (!isKnownNonNegative(AddRec->getOperand(i)))
+ AllNonNeg = false;
+ if (!isKnownNonPositive(AddRec->getOperand(i)))
+ AllNonPos = false;
}
if (AllNonNeg)
ConservativeResult = ConservativeResult.intersectWith(
- ConstantRange(APInt(BitWidth, 0),
- APInt::getSignedMinValue(BitWidth)), RangeType);
+ ConstantRange::getNonEmpty(getSignedRangeMin(AddRec->getStart()),
+ APInt::getSignedMinValue(BitWidth)),
+ RangeType);
else if (AllNonPos)
ConservativeResult = ConservativeResult.intersectWith(
- ConstantRange(APInt::getSignedMinValue(BitWidth),
- APInt(BitWidth, 1)), RangeType);
+ ConstantRange::getNonEmpty(
+ APInt::getSignedMinValue(BitWidth),
+ getSignedRangeMax(AddRec->getStart()) + 1),
+ RangeType);
}
// TODO: non-affine addrec
OpenPOWER on IntegriCloud