Skip to content

Commit d7e631c

Browse files
authored
[RISCV] Remove AND mask generated by ( zext ( atomic_load ) ) by replacing the load with zextload for orderings not stronger then monotonic. (#136502)
Extends changes from [ff687af](ff687af). Fixes #131476. This patch adds a DAG combine to replace an `AND` of an `ATOMIC_LOAD` with a full-bit mask (e.g. `0xFF`, `0xFFFF`, etc.) which is generated as a result of `(zext (atomic_load))`, by a zero-extended load, provided the atomic operation is monotonic or weaker.
1 parent a6f4a54 commit d7e631c

File tree

3 files changed

+94
-143
lines changed

3 files changed

+94
-143
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15321,6 +15321,40 @@ static SDValue reverseZExtICmpCombine(SDNode *N, SelectionDAG &DAG,
1532115321
return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Res);
1532215322
}
1532315323

15324+
static SDValue reduceANDOfAtomicLoad(SDNode *N,
15325+
TargetLowering::DAGCombinerInfo &DCI) {
15326+
SelectionDAG &DAG = DCI.DAG;
15327+
if (N->getOpcode() != ISD::AND)
15328+
return SDValue();
15329+
15330+
SDValue N0 = N->getOperand(0);
15331+
if (N0.getOpcode() != ISD::ATOMIC_LOAD)
15332+
return SDValue();
15333+
if (!N0.hasOneUse())
15334+
return SDValue();
15335+
15336+
AtomicSDNode *ALoad = cast<AtomicSDNode>(N0.getNode());
15337+
if (isStrongerThanMonotonic(ALoad->getSuccessOrdering()))
15338+
return SDValue();
15339+
15340+
EVT LoadedVT = ALoad->getMemoryVT();
15341+
ConstantSDNode *MaskConst = dyn_cast<ConstantSDNode>(N->getOperand(1));
15342+
if (!MaskConst)
15343+
return SDValue();
15344+
uint64_t Mask = MaskConst->getZExtValue();
15345+
uint64_t ExpectedMask = maskTrailingOnes<uint64_t>(LoadedVT.getSizeInBits());
15346+
if (Mask != ExpectedMask)
15347+
return SDValue();
15348+
15349+
SDValue ZextLoad = DAG.getAtomicLoad(
15350+
ISD::ZEXTLOAD, SDLoc(N), ALoad->getMemoryVT(), N->getValueType(0),
15351+
ALoad->getChain(), ALoad->getBasePtr(), ALoad->getMemOperand());
15352+
DCI.CombineTo(N, ZextLoad);
15353+
DAG.ReplaceAllUsesOfValueWith(SDValue(N0.getNode(), 1), ZextLoad.getValue(1));
15354+
DCI.recursivelyDeleteUnusedNodes(N0.getNode());
15355+
return SDValue(N, 0);
15356+
}
15357+
1532415358
// Combines two comparison operation and logic operation to one selection
1532515359
// operation(min, max) and logic operation. Returns new constructed Node if
1532615360
// conditions for optimization are satisfied.
@@ -15355,6 +15389,8 @@ static SDValue performANDCombine(SDNode *N,
1535515389
return V;
1535615390
if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
1535715391
return V;
15392+
if (SDValue V = reduceANDOfAtomicLoad(N, DCI))
15393+
return V;
1535815394

1535915395
if (DCI.isAfterLegalizeDAG())
1536015396
if (SDValue V = combineDeMorganOfBoolean(N, DAG))

llvm/lib/Target/RISCV/RISCVInstrInfoA.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ class seq_cst_store<PatFrag base>
167167
let Predicates = [HasAtomicLdSt] in {
168168
def : LdPat<relaxed_load<atomic_load_asext_8>, LB>;
169169
def : LdPat<relaxed_load<atomic_load_asext_16>, LH>;
170+
def : LdPat<relaxed_load<atomic_load_zext_8>, LBU>;
171+
def : LdPat<relaxed_load<atomic_load_zext_16>, LHU>;
170172

171173
def : StPat<relaxed_store<atomic_store_8>, SB, GPR, XLenVT>;
172174
def : StPat<relaxed_store<atomic_store_16>, SH, GPR, XLenVT>;
@@ -179,6 +181,7 @@ let Predicates = [HasAtomicLdSt, IsRV32] in {
179181

180182
let Predicates = [HasAtomicLdSt, IsRV64] in {
181183
def : LdPat<relaxed_load<atomic_load_asext_32>, LW>;
184+
def : LdPat<relaxed_load<atomic_load_zext_32>, LWU>;
182185
def : LdPat<relaxed_load<atomic_load_nonext_64>, LD, i64>;
183186
def : StPat<relaxed_store<atomic_store_64>, SD, GPR, i64>;
184187
}

0 commit comments

Comments
 (0)