diff options
author | Zheng Chen <czhengsz@cn.ibm.com> | 2020-01-10 22:50:39 -0500 |
---|---|---|
committer | Zheng Chen <czhengsz@cn.ibm.com> | 2020-01-11 23:26:35 -0500 |
commit | 569ccfc384a5434c35c09adba8c44c46014297e6 (patch) | |
tree | 69d40519c37868f045dadeb6c536783c7c7a592a /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | efb674ac2f2b0f06adc3f00df3134dadf1c875df (diff) | |
download | bcm5719-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.cpp | 26 |
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 |