summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-03-18 21:20:03 +0000
committerNikita Popov <nikita.ppv@gmail.com>2019-03-18 21:20:03 +0000
commitf89343bc47dcac93aa333b2363f4a681143c463f (patch)
treeca0bc6bae08718d01e1dacaa22fad7837fd3a805 /llvm/lib/Analysis/ValueTracking.cpp
parent05baa9ee1aea03be7d776d37803188d771d558b7 (diff)
downloadbcm5719-llvm-f89343bc47dcac93aa333b2363f4a681143c463f.tar.gz
bcm5719-llvm-f89343bc47dcac93aa333b2363f4a681143c463f.zip
[ValueTracking][InstSimplify] Move abs handling into computeConstantRange(); NFC
This is preparation for D59506. The InstructionSimplify abs handling is moved into computeConstantRange(), which is the general place for such calculations. This is NFC and doesn't affect the existing tests in test/Transforms/InstSimplify/icmp-abs-nabs.ll. Differential Revision: https://reviews.llvm.org/D59511 llvm-svn: 356409
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ca56ec653d6..00123788f2f 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5653,6 +5653,36 @@ static void setLimitsForIntrinsic(const IntrinsicInst &II, APInt &Lower,
}
}
+static void setLimitsForSelectPattern(const SelectInst &SI, APInt &Lower,
+ APInt &Upper) {
+ const Value *LHS, *RHS;
+ SelectPatternResult R = matchSelectPattern(&SI, LHS, RHS);
+ if (R.Flavor == SPF_UNKNOWN)
+ return;
+
+ unsigned BitWidth = SI.getType()->getScalarSizeInBits();
+
+ // matchSelectPattern() returns the negation part of an abs pattern in RHS.
+ // If the negate has an NSW flag, abs(INT_MIN) is undefined. Without that
+ // constraint, we can't make a contiguous range for the result of abs.
+ if (R.Flavor == SelectPatternFlavor::SPF_ABS &&
+ cast<Instruction>(RHS)->hasNoSignedWrap()) {
+ // The result of abs(X) is >= 0 (with nsw).
+ Lower = APInt::getNullValue(BitWidth);
+ Upper = APInt::getSignedMaxValue(BitWidth) + 1;
+ return;
+ }
+
+ if (R.Flavor == SelectPatternFlavor::SPF_NABS) {
+ // The result of -abs(X) is <= 0.
+ Lower = APInt::getSignedMinValue(BitWidth);
+ Upper = APInt(BitWidth, 1);
+ return;
+ }
+
+ // TODO Handle min/max flavors.
+}
+
ConstantRange llvm::computeConstantRange(const Value *V, bool UseInstrInfo) {
assert(V->getType()->isIntOrIntVectorTy() && "Expected integer instruction");
@@ -5664,6 +5694,8 @@ ConstantRange llvm::computeConstantRange(const Value *V, bool UseInstrInfo) {
setLimitsForBinOp(*BO, Lower, Upper, IIQ);
else if (auto *II = dyn_cast<IntrinsicInst>(V))
setLimitsForIntrinsic(*II, Lower, Upper);
+ else if (auto *SI = dyn_cast<SelectInst>(V))
+ setLimitsForSelectPattern(*SI, Lower, Upper);
ConstantRange CR = Lower != Upper ? ConstantRange(Lower, Upper)
: ConstantRange(BitWidth, true);
OpenPOWER on IntegriCloud