diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-20 18:16:02 +0000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-03-20 18:16:02 +0000 |
commit | 00b5ecab5d8133fe437cf4668b46cb5d2716447f (patch) | |
tree | ea3416a1252194a9877e6e9cf48d64a35510da49 /llvm/lib/Analysis | |
parent | 769c2459d5c201d98c9e96c868dae94e4c7ec1a2 (diff) | |
download | bcm5719-llvm-00b5ecab5d8133fe437cf4668b46cb5d2716447f.tar.gz bcm5719-llvm-00b5ecab5d8133fe437cf4668b46cb5d2716447f.zip |
[ValueTracking] Compute range for abs without nsw
This is a small followup to D59511. The code that was moved into
computeConstantRange() there is a bit overly conversative: If the
abs is not nsw, it does not compute any range. However, abs without
nsw still has a well-defined contiguous unsigned range from 0 to
SIGNED_MIN. This is a lot less useful than the usual 0 to SIGNED_MAX
range, but if we're already here we might as well specify it...
Differential Revision: https://reviews.llvm.org/D59563
llvm-svn: 356586
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 99d6010acee..52328b174b4 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5673,14 +5673,15 @@ static void setLimitsForSelectPattern(const SelectInst &SI, APInt &Lower, 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). + if (R.Flavor == SelectPatternFlavor::SPF_ABS) { + // If the negation part of the abs (in RHS) has the NSW flag, + // then the result of abs(X) is [0..SIGNED_MAX], + // otherwise it is [0..SIGNED_MIN], as -SIGNED_MIN == SIGNED_MIN. Lower = APInt::getNullValue(BitWidth); - Upper = APInt::getSignedMaxValue(BitWidth) + 1; + if (cast<Instruction>(RHS)->hasNoSignedWrap()) + Upper = APInt::getSignedMaxValue(BitWidth) + 1; + else + Upper = APInt::getSignedMinValue(BitWidth) + 1; return; } |