[llvm] [InstCombine] Fold rotate patterns with ZExt/Trunc at different Points (PR #142578)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 11 01:15:49 PDT 2025


================
@@ -2969,31 +2969,53 @@ InstCombinerImpl::convertOrOfShiftsToFunnelShift(Instruction &Or) {
       if (!isPowerOf2_32(Width))
         return nullptr;
 
-      // The shift amount may be masked with negation:
-      // (shl ShVal, (X & (Width - 1))) | (lshr ShVal, ((-X) & (Width - 1)))
+      // Check that L and R operate on the same value X. Since the bitwidth of X
+      // can differ from L and R, there are multiple possible locations of ZExt
+      // or Trunc.
       Value *X;
+      const APInt *LMask = nullptr;
+      const APInt *RMask = nullptr;
       unsigned Mask = Width - 1;
-      if (match(L, m_And(m_Value(X), m_SpecificInt(Mask))) &&
-          match(R, m_And(m_Neg(m_Specific(X)), m_SpecificInt(Mask))))
-        return X;
+      // L is essentially a no-op except for changing the type of X.
+      // There are multiple pattern like X & LMask or ZExt/Trunc
+      match(L, m_TruncOrZExtOrSelf(m_CombineOr(
+                   m_And(m_TruncOrZExtOrSelf(m_Value(X)), m_APInt(LMask)),
+                   m_Value(X))));
----------------
RKSimon wrote:

not sure if its safe to do this with X being potentially written in 2 locations in the match?

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


More information about the llvm-commits mailing list