[llvm] [InstCombine] Canonicalise packed-integer-selecting shifts (PR #162147)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 7 01:09:15 PDT 2025


================
@@ -800,6 +800,48 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
         Known.Zero.setHighBits(ShiftAmt);  // high bits known zero.
     } else {
       llvm::computeKnownBits(I, Known, Q, Depth);
+
+      // Let N = 2 * M.
+      // Given an N-bit integer representing a pack of two M-bit integers,
+      // we can select one of the packed integers by right-shifting by either
+      // zero or M (which is the most straightforward to check if M is a power
+      // of 2), and then isolating the lower M bits. In this case, we can
+      // represent the shift as a select on whether the shr amount is nonzero.
+      uint64_t ShlAmt;
+      Value *Upper, *Lower;
+      if (!match(I->getOperand(0),
+                 m_OneUse(m_DisjointOr(
+                     m_OneUse(m_Shl(m_Value(Upper), m_ConstantInt(ShlAmt))),
+                     m_Value(Lower)))))
+        break;
+      if (!isPowerOf2_64(ShlAmt))
+        break;
+
+      const uint64_t DemandedBitWidth = DemandedMask.getActiveBits();
+      if (DemandedBitWidth > ShlAmt)
+        break;
+
+      // Check that upper demanded bits are not lost from lshift.
+      if (Upper->getType()->getScalarSizeInBits() < ShlAmt + DemandedBitWidth)
+        break;
+
+      KnownBits KnownLowerBits = computeKnownBits(Lower, I, Depth);
+      if (!KnownLowerBits.getMaxValue().isIntN(ShlAmt))
+        break;
+
+      Value *ShrAmt = I->getOperand(1);
+      KnownBits KnownShrBits = computeKnownBits(ShrAmt, I, Depth);
+      // Verify that ShrAmt is either exactly ShlAmt (which is a power of 2) or
+      // zero.
+      if ((~KnownShrBits.Zero).getZExtValue() != ShlAmt)
----------------
dtcxzyw wrote:

```suggestion
      if ((~KnownShrBits.Zero) != ShlAmt)
```
It may assert on i128 APInt values.


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


More information about the llvm-commits mailing list