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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 3 12:44:58 PDT 2024


================
@@ -1624,12 +1624,44 @@ 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);
+  if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap) {
+    std::optional<unsigned> ShAmtBound;
+    if (isAllNonNegative())
+      ShAmtBound = getSignedMin().countLeadingZeros();
+    else if (isAllNegative())
+      ShAmtBound = getSignedMax().countLeadingOnes();
+    ConstantRange ShAmtRange = Other;
+    if (ShAmtBound)
+      ShAmtRange = ShAmtRange.intersectWith(
+          ConstantRange(APInt(getBitWidth(), 0),
+                        APInt(getBitWidth(), *ShAmtBound)),
+          Unsigned);
+    Result = Result.intersectWith(sshl_sat(ShAmtRange), RangeType);
+  }
 
-  if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap)
-    Result = Result.intersectWith(ushl_sat(Other), RangeType);
+  if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap) {
----------------
nikic wrote:

I think you should be able to skip the shl() call now for the nuw case, as the implementation is optimal by itself.

I'm also wondering whether it's easy to make the nuw+nsw case optimal. We effectively have one less bit to work with in that case.

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


More information about the llvm-commits mailing list