[llvm] [DemandedBits] Support non-constant shift amounts (PR #148880)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 2 09:08:37 PDT 2025


================
@@ -76,6 +76,19 @@ void DemandedBits::determineLiveOperandBits(
           computeKnownBits(V2, Known2, DL, &AC, UserI, &DT);
         }
       };
+  auto GetShiftedRange = [&](uint64_t Min, uint64_t Max, bool ShiftLeft) {
+    auto ShiftF = [ShiftLeft](const APInt &Mask, unsigned ShiftAmnt) {
+      return ShiftLeft ? Mask.shl(ShiftAmnt) : Mask.lshr(ShiftAmnt);
+    };
+    AB = APInt::getZero(BitWidth);
+    uint64_t LoopRange = Max - Min;
+    APInt Mask = AOut;
+    for (unsigned ShiftAmnt = 1; ShiftAmnt <= LoopRange; ShiftAmnt <<= 1) {
+      APInt Shifted = ShiftF(Mask, ShiftAmnt);
+      Mask |= Shifted;
+    }
----------------
dtcxzyw wrote:

It looks like an overestimation. See the following case:
```
AOut = 00000001 Min = 0 Max = 4 ShiftLeft = true
Expected Mask = 00011111

Mask = 00000001
ShiftAmnt = 1 Mask = 00000011
ShiftAmnt = 2 Mask = 00001111
ShiftAmnt = 4 Mask = 11111111
```

```suggestion
    APInt Shifted = AOut; // AOut | (AOut << 1) | ... | (AOut << (ShiftAmnt - 1)
    for (unsigned ShiftAmnt = 1; ShiftAmnt <= LoopRange; ShiftAmnt <<= 1) {
      if (LoopRange & ShiftAmnt) {
        // Account for (LoopRange - ShiftAmnt, LoopRange]
        Mask |= ShiftF(Shifted, LoopRange - ShiftAmnt + 1);
        // Clears the low bit.
        LoopRange -= ShiftAmnt;
      }
      // [0, ShiftAmnt) -> [0, ShiftAmnt * 2)
      Shifted |= ShiftF(Shifted, ShiftAmnt);
    }
```


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


More information about the llvm-commits mailing list