[llvm] [RISCV] Introduce new AND combine to expose additional load narrowing opportunities (PR #170483)
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 3 11:36:49 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))) {
----------------
preames wrote:
Hm, actually, I think we might want to exploring doing this even if the op *isn't* a load. The shifted masks correspond to zext.b/h/w. W has all the uw variants. zext.w is in zba, zext.h is in zbb, zext.b in base, and all the compressed variants in zcb. These are likely either going to fold into something, or if not, be cheaper/smaller than the shifted mask formation.
(As a possible follow up is totally fine.)
https://github.com/llvm/llvm-project/pull/170483
More information about the llvm-commits
mailing list