[llvm] [GlobalISel] [AArch64] Skip redundant shift amount masking during isel (PR #223136)

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 02:57:59 PDT 2026


================
@@ -766,6 +769,30 @@ bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
   return true;
 }
 
+template <unsigned ShiftWidth>
+bool AArch64DAGToDAGISel::SelectShiftMask(SDValue N, SDValue &ShAmt) {
+  // AArch64 shift instructions only use the low log2(ShiftWidth) bits of the
+  // shift amount. If the shift amount has a redundant AND mask that exactly
+  // covers a narrow type, we can remove it.
+  // Note: do not strip ZERO_EXTEND/ANY_EXTEND here as that can cause
+  // register class mismatches (e.g. returning a 32-bit value for an i64 shift).
+  // Do not match ZERO_EXTEND or ANY_EXTEND — these are handled by existing
+  // patterns in the Shift multiclass (e.g. zext GPR32 → SUBREG_TO_REG).
+  if (N.getOpcode() == ISD::ZERO_EXTEND || N.getOpcode() == ISD::ANY_EXTEND)
+    return false;
+
+  if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1)) &&
+      N.getValueType() == (ShiftWidth == 32 ? MVT::i32 : MVT::i64)) {
+    uint64_t Mask = N.getConstantOperandVal(1);
+    // Only remove AND if it exactly masks a narrow type (byte, halfword, word).
+    if (Mask == 0xff || Mask == 0xffff || Mask == 0xffffffff)
+      N = N.getOperand(0);
+  }
+
+  ShAmt = N;
+  return true;
----------------
davemgreen wrote:

Return false if we didn't find anything worth combining?

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


More information about the llvm-commits mailing list