[llvm] [ConstantRange] Improve `shlWithNoWrap` (PR #101800)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 3 11:03:12 PDT 2024


================
@@ -1624,12 +1624,43 @@ ConstantRange ConstantRange::shlWithNoWrap(const ConstantRange &Other,
     return getEmpty();
 
   ConstantRange Result = shl(Other);
+  if (!NoWrapKind)
+    return Result;
 
-  if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap)
-    Result = Result.intersectWith(sshl_sat(Other), RangeType);
+  KnownBits Known = toKnownBits();
+
+  if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap) {
+    ConstantRange ShAmtRange = Other;
+    if (isAllNonNegative())
+      ShAmtRange = ShAmtRange.intersectWith(
+          ConstantRange(APInt::getZero(getBitWidth()),
+                        APInt(getBitWidth(), Known.countMaxLeadingZeros())),
+          Unsigned);
+    else if (isAllNegative())
+      ShAmtRange = ShAmtRange.intersectWith(
+          ConstantRange(APInt::getZero(getBitWidth()),
+                        APInt(getBitWidth(), Known.countMaxLeadingOnes())),
+          Unsigned);
+    Result = Result.intersectWith(sshl_sat(ShAmtRange), RangeType);
+  }
 
-  if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap)
-    Result = Result.intersectWith(ushl_sat(Other), RangeType);
+  if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap) {
+    bool Overflow;
+    APInt LHSMin = getUnsignedMin();
+    APInt MinShl = LHSMin.ushl_ov(Other.getUnsignedMin(), Overflow);
+    if (Overflow)
+      return getEmpty();
+    APInt LHSMax = getUnsignedMax();
+    APInt MaxShl = LHSMax << Other.getUnsignedMax().getLimitedValue(
+                       LHSMax.countLeadingZeros());
+    if (LHSMin.countLeadingZeros() != LHSMax.countLeadingZeros())
+      MaxShl = APIntOps::umax(
+          MaxShl, APInt::getHighBitsSet(
----------------
dtcxzyw wrote:

Consider the following case:
```
%x = [3, 5)
%y = Full
%shl = shl nuw i8 %x, %y
```
We have
```
4 << ctlz(4) = 128
3 << ctlz(3) = 192
```



https://github.com/llvm/llvm-project/pull/101800


More information about the llvm-commits mailing list