[llvm] [GISel] Combine shift + trunc + shift pattern (PR #155583)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 1 06:57:31 PDT 2025


================
@@ -2094,6 +2094,60 @@ bool CombinerHelper::matchCommuteShift(MachineInstr &MI,
   return true;
 }
 
+bool CombinerHelper::matchShiftOfTruncOfShift(
+    MachineInstr &MI, ShiftOfTruncOfShift &MatchInfo) const {
+  unsigned ShiftOpcode = MI.getOpcode();
+  assert(ShiftOpcode == TargetOpcode::G_LSHR ||
+         ShiftOpcode == TargetOpcode::G_ASHR);
+
+  Register N0 = MI.getOperand(1).getReg();
+  Register N1 = MI.getOperand(2).getReg();
+  unsigned OpSizeInBits = MRI.getType(N0).getScalarSizeInBits();
+
+  APInt N1C;
+  Register InnerShift;
+  if (!mi_match(N1, MRI, m_ICstOrSplat(N1C)) ||
+      !mi_match(N0, MRI, m_GTrunc(m_Reg(InnerShift))))
+    return false;
+
+  auto *InnerMI = MRI.getVRegDef(InnerShift);
+  if (InnerMI->getOpcode() != ShiftOpcode)
+    return false;
+
+  APInt N001C;
+  auto N001 = InnerMI->getOperand(2).getReg();
+  if (!mi_match(N001, MRI, m_ICstOrSplat(N001C)))
+    return false;
+
+  uint64_t c1 = N001C.getZExtValue();
+  uint64_t c2 = N1C.getZExtValue();
+  LLT InnerShiftTy = MRI.getType(InnerShift);
+  uint64_t InnerShiftSize = InnerShiftTy.getScalarSizeInBits();
+  if (!(c1 + OpSizeInBits == InnerShiftSize) || !(c1 + c2 < InnerShiftSize))
----------------
jyli0116 wrote:

When looking at DAGCombiner.cpp, i think the comments mentioned that this specific pattern is only valid under this condition, and in the general case, we have a mask - the general case can probably be added to the apply function as well

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


More information about the llvm-commits mailing list