[PATCH] D151540: [KnownBits] Add fast-path for shl with unknown shift amount

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 26 01:14:12 PDT 2023


nikic created this revision.
nikic added reviewers: foad, RKSimon, goldstein.w.n.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

We currently don't call into KnownBits::shl from ValueTracking if the shift amount is unknown. If we do try to do so, we get significant compile-time regressions, because evaluating all 64 shift amounts if quite expensive, and mostly pointless in this case. Add a fast-path for the case where the shift amount is the full [0, BitWidth-1] range. This primarily requires a more accurate estimate of the max shift amount, to avoid taking the fast-path in too many cases.


https://reviews.llvm.org/D151540

Files:
  llvm/lib/Support/KnownBits.cpp


Index: llvm/lib/Support/KnownBits.cpp
===================================================================
--- llvm/lib/Support/KnownBits.cpp
+++ llvm/lib/Support/KnownBits.cpp
@@ -218,8 +218,33 @@
     return Known;
   }
 
+  // Determine maximum shift amount, taking NUW/NSW flags into account.
+  APInt MaxValue = RHS.getMaxValue();
+  if (isPowerOf2_32(BitWidth))
+    MaxValue &= APInt::getLowBitsSet(BitWidth, Log2_32(BitWidth));
+  unsigned MaxShiftAmount = MaxValue.getLimitedValue(BitWidth - 1);
+  if (NUW)
+    MaxShiftAmount = std::min(MaxShiftAmount, LHS.countMaxLeadingZeros());
+  if (NSW)
+    MaxShiftAmount = std::min(
+        MaxShiftAmount,
+        std::max(LHS.countMaxLeadingZeros(), LHS.countMaxLeadingOnes()) - 1);
+
+  // Fast path for common case where the shift amount is unknown.
+  if (MinShiftAmount == 0 && MaxShiftAmount == BitWidth - 1) {
+    Known.Zero.setLowBits(LHS.countMinTrailingZeros());
+    if (LHS.isAllOnes())
+      Known.One.setSignBit();
+    if (NSW) {
+      if (LHS.isNonNegative())
+        Known.makeNonNegative();
+      if (LHS.isNegative())
+        Known.makeNegative();
+    }
+    return Known;
+  }
+
   // Find the common bits from all possible shifts.
-  unsigned MaxShiftAmount = RHS.getMaxValue().getLimitedValue(BitWidth - 1);
   unsigned ShiftAmtZeroMask = RHS.Zero.zextOrTrunc(32).getZExtValue();
   unsigned ShiftAmtOneMask = RHS.One.zextOrTrunc(32).getZExtValue();
   Known.Zero.setAllBits();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151540.525971.patch
Type: text/x-patch
Size: 1463 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230526/5ba91bf2/attachment.bin>


More information about the llvm-commits mailing list