[llvm] [RISCV] Remove `AND` mask generated by `( zext ( atomic_load ) )` by replacing the load with `zextload` for orderings not stronger then monotonic. (PR #136502)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 23 18:03:48 PDT 2025
Jan =?utf-8?q?Górski?= <jan.a.gorski at wp.pl>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/136502 at github.com>
================
@@ -15267,6 +15267,48 @@ static SDValue reverseZExtICmpCombine(SDNode *N, SelectionDAG &DAG,
return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Res);
}
+static SDValue reduceANDOfAtomicLoad(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ SelectionDAG &DAG = DCI.DAG;
+ if (N->getOpcode() != ISD::AND)
+ return SDValue();
+
+ SDValue N0 = N->getOperand(0);
+ if (N0.getOpcode() != ISD::ATOMIC_LOAD)
+ return SDValue();
+
+ AtomicSDNode *ALoad = cast<AtomicSDNode>(N0.getNode());
+ if (isStrongerThanMonotonic(ALoad->getSuccessOrdering()))
+ return SDValue();
+
+ EVT LoadedVT = ALoad->getMemoryVT();
+ EVT ResultVT = N->getValueType(0);
+
+ SDValue MaskVal = N->getOperand(1);
+ ConstantSDNode *MaskConst = dyn_cast<ConstantSDNode>(MaskVal);
+ if (!MaskConst)
+ return SDValue();
+ uint64_t Mask = MaskConst->getZExtValue();
+ uint64_t ExpectedMask = LoadedVT.getSizeInBits() == 8 ? 0xFF
+ : LoadedVT.getSizeInBits() == 16 ? 0xFFFF
+ : LoadedVT.getSizeInBits() == 32 ? 0xFFFFFFFF
+ : 0xFFFFFFFFFFFFFFFF;
+ if (Mask != ExpectedMask)
+ return SDValue();
+
+ SDLoc DL(N);
+ SDValue Chain = ALoad->getChain();
+ SDValue Ptr = ALoad->getBasePtr();
+ MachineMemOperand *MemOp = ALoad->getMemOperand();
+ SDValue ZextLoad = DAG.getExtLoad(ISD::ZEXTLOAD, DL, ResultVT, Chain, Ptr,
+ MemOp->getPointerInfo(), LoadedVT,
+ MemOp->getAlign(), MemOp->getFlags());
+ DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), ZextLoad);
----------------
topperc wrote:
We should use `DCI.CombineTo(N, ZextLoad)` instead of `DAG.ReplaceAllUsesOfValueWith`
https://github.com/llvm/llvm-project/pull/136502
More information about the llvm-commits
mailing list