diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-18 21:20:03 +0000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-18 21:20:03 +0000 |
commit | f89343bc47dcac93aa333b2363f4a681143c463f (patch) | |
tree | ca0bc6bae08718d01e1dacaa22fad7837fd3a805 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 05baa9ee1aea03be7d776d37803188d771d558b7 (diff) | |
download | bcm5719-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.cpp | 32 |
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); |