-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[ValueTracking] If overlap in unsigned and signed range is contiguous, return it #144267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-llvm-analysis Author: AZero13 (AZero13) ChangesWe have to choose between unsigned and signed if there are two overlaps, aka the range wraps around, meaning [254,255] vs. signed [-128, 125], but [254,255] correspond to [-2 -1] which is in the range [-128, 125]. However, a range that would not work would be one where one has to pick between [0, 129] vs [-127, 127] because 129 is -2 signed. Full diff: https://github.com/llvm/llvm-project/pull/144267.diff 1 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index e7a1f07c0270d..11f20ce9671ba 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -9585,6 +9585,30 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
bool HasNSW = IIQ.hasNoSignedWrap(&BO);
bool HasNUW = IIQ.hasNoUnsignedWrap(&BO);
+ if (HasNUW && HasNSW) {
+ APInt uLo = APInt::getZero(Width);
+ APInt uHi = *C + 1;
+
+ APInt sLo, sHi;
+ if (C->isNegative()) {
+ sLo = APInt::getSignedMinValue(Width);
+ sHi = APInt::getSignedMaxValue(Width) + *C + 2;
+ } else {
+ sLo = APInt::getSignedMinValue(Width) + *C + 1;
+ sHi = APInt::getSignedMaxValue(Width) + 1;
+ }
+
+ APInt iLo = APIntOps::smax(uLo, sLo);
+ APInt iHi = APIntOps::smin(uHi, sHi);
+
+ if (iLo.ult(iHi) && iLo.sge(APInt::getSignedMinValue(Width)) &&
+ (iHi - 1).sle(APInt::getSignedMaxValue(Width))) {
+ Lower = iLo;
+ Upper = iHi;
+ break;
+ }
+ }
+
// If the caller expects a signed compare, then try to use a signed range.
// Otherwise if both no-wraps are set, use the unsigned range because it
// is never larger than the signed range. Example:
@@ -9615,6 +9639,31 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
bool HasNSW = IIQ.hasNoSignedWrap(&BO);
bool HasNUW = IIQ.hasNoUnsignedWrap(&BO);
+ if (HasNUW && HasNSW) {
+ APInt uLo = *C;
+ APInt uHi = APInt::getZero(Width);
+
+ APInt sLo, sHi;
+ if (C->isNegative()) {
+ sLo = APInt::getSignedMinValue(Width);
+ sHi = APInt::getSignedMaxValue(Width) + *C + 1;
+ } else {
+ sLo = APInt::getSignedMinValue(Width) + *C;
+ sHi = APInt::getSignedMaxValue(Width) + 1;
+ }
+
+ APInt iLo = APIntOps::smax(uLo, sLo);
+ APInt iHi = APIntOps::smin(uHi, sHi);
+
+ if (iLo.ult(iHi) &&
+ iLo.sge(APInt::getSignedMinValue(Width)) &&
+ (iHi - 1).sle(APInt::getSignedMaxValue(Width))) {
+ Lower = iLo;
+ Upper = iHi;
+ break;
+ }
+ }
+
// If the caller expects a signed compare, then try to use a signed
// range. Otherwise if both no-wraps are set, use the unsigned range
// because it is never larger than the signed range. Example: "add nuw
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
813a4e9
to
4d57702
Compare
…, return it We have to choose between unsigned and signed if there are two overlaps, aka the range wraps around, meaning [254,255] vs. signed [-128, 125], but [254,255] correspond to [-2 -1] which is in the range [-128, 125]. However, a range that would not work would be one where one has to pick between [0, 129] vs [-127, 127] because 129 is -2 signed. Update ValueTracking.cpp Revert "[ValueTracking] If overlap in unsigned and signed range is contiguous, return it" This reverts commit 22e997c489aad3173db78f6fee17212bd16be96d. ok
We have to choose between unsigned and signed if there are two overlaps, aka the range wraps around, meaning [254,255] vs. signed [-128, 125], but [254,255] correspond to [-2 -1] which is in the range [-128, 125].
However, a range that would not work would be one where one has to pick between [0, 129] vs [-127, 127] because 129 is -2 signed.