[llvm] [RISCV] Introduce new AND combine to expose additional load narrowing opportunities (PR #170483)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 3 11:57:30 PST 2025


================
@@ -16607,6 +16607,38 @@ static SDValue performANDCombine(SDNode *N,
   SelectionDAG &DAG = DCI.DAG;
 
   SDValue N0 = N->getOperand(0);
+  SDValue N1 = N->getOperand(1);
+
+  // Sometimes a mask is applied after a shift. If that shift was fed by a
+  // load, there is sometimes the opportunity to narrow the load, which is
+  // hidden by the intermediate shift. Detect that case and commute the
+  // shift/and in order to enable load narrowing.
+  if (N0.getOpcode() == ISD::SHL && N0.hasOneUse() && isa<ConstantSDNode>(N1) &&
+      isa<ConstantSDNode>(N0.getOperand(1))) {
+
+    EVT VT = N->getValueType(0);
+    auto *MaskC = cast<ConstantSDNode>(N1);
+    auto *ShiftC = cast<ConstantSDNode>(N0.getOperand(1));
+
+    uint64_t ShiftAmt = ShiftC->getZExtValue();
+    APInt MaskVal = MaskC->getAPIntValue();
+    // Calculate the mask if it were applied before the shift.
+    APInt InnerMask = MaskVal.lshr(ShiftAmt);
+
+    bool IsNarrowable =
+        InnerMask == 0xff || InnerMask == 0xffff || InnerMask == 0xffffffff;
+
+    if (IsNarrowable && isa<LoadSDNode>(N0.getOperand(0))) {
----------------
topperc wrote:

> These are likely either going to fold into something, or if not, be cheaper/smaller than the shifted mask formation.

I think and+shl and shl+and both isel as a slli+srli pair in RISCVISelDAGToDAG.cpp. slli and srli are just as compressible as an alternative using Zcb.

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


More information about the llvm-commits mailing list