summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-06-15 09:15:52 +0000
committerNikita Popov <nikita.ppv@gmail.com>2019-06-15 09:15:52 +0000
commit8550fb386a367f15987019f7fa00c843dfde6a97 (patch)
tree818923c9cccf190a5c0c31538b796690e3e6d1c0 /llvm/lib/Analysis/ScalarEvolution.cpp
parent9145562b4879b34ae5c21af27be4162484f9602e (diff)
downloadbcm5719-llvm-8550fb386a367f15987019f7fa00c843dfde6a97.tar.gz
bcm5719-llvm-8550fb386a367f15987019f7fa00c843dfde6a97.zip
[SCEV] Use unsigned/signed intersection type in SCEV
Based on D59959, this switches SCEV to use unsigned/signed range intersection based on the sign hint. This will prefer non-wrapping ranges in the relevant domain. I've left the one intersection in getRangeForAffineAR() to use the smallest intersection heuristic, as there doesn't seem to be any obvious preference there. Differential Revision: https://reviews.llvm.org/D60035 llvm-svn: 363490
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp51
1 files changed, 32 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 88686427127..f37581fbded 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5535,6 +5535,9 @@ ScalarEvolution::getRangeRef(const SCEV *S,
DenseMap<const SCEV *, ConstantRange> &Cache =
SignHint == ScalarEvolution::HINT_RANGE_UNSIGNED ? UnsignedRanges
: SignedRanges;
+ ConstantRange::PreferredRangeType RangeType =
+ SignHint == ScalarEvolution::HINT_RANGE_UNSIGNED
+ ? ConstantRange::Unsigned : ConstantRange::Signed;
// See if we've computed this range already.
DenseMap<const SCEV *, ConstantRange>::iterator I = Cache.find(S);
@@ -5565,53 +5568,60 @@ ScalarEvolution::getRangeRef(const SCEV *S,
ConstantRange X = getRangeRef(Add->getOperand(0), SignHint);
for (unsigned i = 1, e = Add->getNumOperands(); i != e; ++i)
X = X.add(getRangeRef(Add->getOperand(i), SignHint));
- return setRange(Add, SignHint, ConservativeResult.intersectWith(X));
+ return setRange(Add, SignHint,
+ ConservativeResult.intersectWith(X, RangeType));
}
if (const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(S)) {
ConstantRange X = getRangeRef(Mul->getOperand(0), SignHint);
for (unsigned i = 1, e = Mul->getNumOperands(); i != e; ++i)
X = X.multiply(getRangeRef(Mul->getOperand(i), SignHint));
- return setRange(Mul, SignHint, ConservativeResult.intersectWith(X));
+ return setRange(Mul, SignHint,
+ ConservativeResult.intersectWith(X, RangeType));
}
if (const SCEVSMaxExpr *SMax = dyn_cast<SCEVSMaxExpr>(S)) {
ConstantRange X = getRangeRef(SMax->getOperand(0), SignHint);
for (unsigned i = 1, e = SMax->getNumOperands(); i != e; ++i)
X = X.smax(getRangeRef(SMax->getOperand(i), SignHint));
- return setRange(SMax, SignHint, ConservativeResult.intersectWith(X));
+ return setRange(SMax, SignHint,
+ ConservativeResult.intersectWith(X, RangeType));
}
if (const SCEVUMaxExpr *UMax = dyn_cast<SCEVUMaxExpr>(S)) {
ConstantRange X = getRangeRef(UMax->getOperand(0), SignHint);
for (unsigned i = 1, e = UMax->getNumOperands(); i != e; ++i)
X = X.umax(getRangeRef(UMax->getOperand(i), SignHint));
- return setRange(UMax, SignHint, ConservativeResult.intersectWith(X));
+ return setRange(UMax, SignHint,
+ ConservativeResult.intersectWith(X, RangeType));
}
if (const SCEVUDivExpr *UDiv = dyn_cast<SCEVUDivExpr>(S)) {
ConstantRange X = getRangeRef(UDiv->getLHS(), SignHint);
ConstantRange Y = getRangeRef(UDiv->getRHS(), SignHint);
return setRange(UDiv, SignHint,
- ConservativeResult.intersectWith(X.udiv(Y)));
+ ConservativeResult.intersectWith(X.udiv(Y), RangeType));
}
if (const SCEVZeroExtendExpr *ZExt = dyn_cast<SCEVZeroExtendExpr>(S)) {
ConstantRange X = getRangeRef(ZExt->getOperand(), SignHint);
return setRange(ZExt, SignHint,
- ConservativeResult.intersectWith(X.zeroExtend(BitWidth)));
+ ConservativeResult.intersectWith(X.zeroExtend(BitWidth),
+ RangeType));
}
if (const SCEVSignExtendExpr *SExt = dyn_cast<SCEVSignExtendExpr>(S)) {
ConstantRange X = getRangeRef(SExt->getOperand(), SignHint);
return setRange(SExt, SignHint,
- ConservativeResult.intersectWith(X.signExtend(BitWidth)));
+ ConservativeResult.intersectWith(X.signExtend(BitWidth),
+ RangeType));
}
if (const SCEVTruncateExpr *Trunc = dyn_cast<SCEVTruncateExpr>(S)) {
ConstantRange X = getRangeRef(Trunc->getOperand(), SignHint);
return setRange(Trunc, SignHint,
- ConservativeResult.intersectWith(X.truncate(BitWidth)));
+ ConservativeResult.intersectWith(X.truncate(BitWidth),
+ RangeType));
}
if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
@@ -5621,7 +5631,7 @@ ScalarEvolution::getRangeRef(const SCEV *S,
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(AddRec->getStart()))
if (!C->getValue()->isZero())
ConservativeResult = ConservativeResult.intersectWith(
- ConstantRange(C->getAPInt(), APInt(BitWidth, 0)));
+ 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.
@@ -5635,11 +5645,11 @@ ScalarEvolution::getRangeRef(const SCEV *S,
if (AllNonNeg)
ConservativeResult = ConservativeResult.intersectWith(
ConstantRange(APInt(BitWidth, 0),
- APInt::getSignedMinValue(BitWidth)));
+ APInt::getSignedMinValue(BitWidth)), RangeType);
else if (AllNonPos)
ConservativeResult = ConservativeResult.intersectWith(
ConstantRange(APInt::getSignedMinValue(BitWidth),
- APInt(BitWidth, 1)));
+ APInt(BitWidth, 1)), RangeType);
}
// TODO: non-affine addrec
@@ -5652,14 +5662,14 @@ ScalarEvolution::getRangeRef(const SCEV *S,
BitWidth);
if (!RangeFromAffine.isFullSet())
ConservativeResult =
- ConservativeResult.intersectWith(RangeFromAffine);
+ ConservativeResult.intersectWith(RangeFromAffine, RangeType);
auto RangeFromFactoring = getRangeViaFactoring(
AddRec->getStart(), AddRec->getStepRecurrence(*this), MaxBECount,
BitWidth);
if (!RangeFromFactoring.isFullSet())
ConservativeResult =
- ConservativeResult.intersectWith(RangeFromFactoring);
+ ConservativeResult.intersectWith(RangeFromFactoring, RangeType);
}
}
@@ -5670,7 +5680,8 @@ ScalarEvolution::getRangeRef(const SCEV *S,
// Check if the IR explicitly contains !range metadata.
Optional<ConstantRange> MDRange = GetRangeFromMetadata(U->getValue());
if (MDRange.hasValue())
- ConservativeResult = ConservativeResult.intersectWith(MDRange.getValue());
+ ConservativeResult = ConservativeResult.intersectWith(MDRange.getValue(),
+ RangeType);
// Split here to avoid paying the compile-time cost of calling both
// computeKnownBits and ComputeNumSignBits. This restriction can be lifted
@@ -5681,8 +5692,8 @@ ScalarEvolution::getRangeRef(const SCEV *S,
KnownBits Known = computeKnownBits(U->getValue(), DL, 0, &AC, nullptr, &DT);
if (Known.One != ~Known.Zero + 1)
ConservativeResult =
- ConservativeResult.intersectWith(ConstantRange(Known.One,
- ~Known.Zero + 1));
+ ConservativeResult.intersectWith(
+ ConstantRange(Known.One, ~Known.Zero + 1), RangeType);
} else {
assert(SignHint == ScalarEvolution::HINT_RANGE_SIGNED &&
"generalize as needed!");
@@ -5690,7 +5701,8 @@ ScalarEvolution::getRangeRef(const SCEV *S,
if (NS > 1)
ConservativeResult = ConservativeResult.intersectWith(
ConstantRange(APInt::getSignedMinValue(BitWidth).ashr(NS - 1),
- APInt::getSignedMaxValue(BitWidth).ashr(NS - 1) + 1));
+ APInt::getSignedMaxValue(BitWidth).ashr(NS - 1) + 1),
+ RangeType);
}
// A range of Phi is a subset of union of all ranges of its input.
@@ -5705,7 +5717,8 @@ ScalarEvolution::getRangeRef(const SCEV *S,
if (RangeFromOps.isFullSet())
break;
}
- ConservativeResult = ConservativeResult.intersectWith(RangeFromOps);
+ ConservativeResult =
+ ConservativeResult.intersectWith(RangeFromOps, RangeType);
bool Erased = PendingPhiRanges.erase(Phi);
assert(Erased && "Failed to erase Phi properly?");
(void) Erased;
@@ -5812,7 +5825,7 @@ ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
MaxBECountValue, BitWidth, /* Signed = */ false);
// Finally, intersect signed and unsigned ranges.
- return SR.intersectWith(UR);
+ return SR.intersectWith(UR, ConstantRange::Smallest);
}
ConstantRange ScalarEvolution::getRangeViaFactoring(const SCEV *Start,
OpenPOWER on IntegriCloud