Skip to content

Commit 1c0ac80

Browse files
[DAG] Combine store + vselect to masked_store (#145176)
Add a new combine to replace ``` (store ch (vselect cond truevec (load ch ptr offset)) ptr offset) ``` to ``` (mstore ch truevec ptr offset cond) ``` This saves a blend operation on targets that support conditional stores.
1 parent cd8f348 commit 1c0ac80

13 files changed

+3750
-377
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22534,6 +22534,56 @@ SDValue DAGCombiner::visitATOMIC_STORE(SDNode *N) {
2253422534
return SDValue();
2253522535
}
2253622536

22537+
static SDValue foldToMaskedStore(StoreSDNode *Store, SelectionDAG &DAG,
22538+
const SDLoc &Dl) {
22539+
if (!Store->isSimple() || !ISD::isNormalStore(Store))
22540+
return SDValue();
22541+
22542+
SDValue StoredVal = Store->getValue();
22543+
SDValue StorePtr = Store->getBasePtr();
22544+
SDValue StoreOffset = Store->getOffset();
22545+
EVT VT = Store->getMemoryVT();
22546+
unsigned AddrSpace = Store->getAddressSpace();
22547+
Align Alignment = Store->getAlign();
22548+
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
22549+
22550+
if (!TLI.isOperationLegalOrCustom(ISD::MSTORE, VT) ||
22551+
!TLI.allowsMisalignedMemoryAccesses(VT, AddrSpace, Alignment))
22552+
return SDValue();
22553+
22554+
SDValue Mask, OtherVec, LoadCh;
22555+
unsigned LoadPos;
22556+
if (sd_match(StoredVal,
22557+
m_VSelect(m_Value(Mask), m_Value(OtherVec),
22558+
m_Load(m_Value(LoadCh), m_Specific(StorePtr),
22559+
m_Specific(StoreOffset))))) {
22560+
LoadPos = 2;
22561+
} else if (sd_match(StoredVal,
22562+
m_VSelect(m_Value(Mask),
22563+
m_Load(m_Value(LoadCh), m_Specific(StorePtr),
22564+
m_Specific(StoreOffset)),
22565+
m_Value(OtherVec)))) {
22566+
LoadPos = 1;
22567+
} else {
22568+
return SDValue();
22569+
}
22570+
22571+
auto *Load = cast<LoadSDNode>(StoredVal.getOperand(LoadPos));
22572+
if (!Load->isSimple() || !ISD::isNormalLoad(Load) ||
22573+
Load->getAddressSpace() != AddrSpace)
22574+
return SDValue();
22575+
22576+
if (!Store->getChain().reachesChainWithoutSideEffects(LoadCh))
22577+
return SDValue();
22578+
22579+
if (LoadPos == 1)
22580+
Mask = DAG.getNOT(Dl, Mask, Mask.getValueType());
22581+
22582+
return DAG.getMaskedStore(Store->getChain(), Dl, OtherVec, StorePtr,
22583+
StoreOffset, Mask, VT, Store->getMemOperand(),
22584+
Store->getAddressingMode());
22585+
}
22586+
2253722587
SDValue DAGCombiner::visitSTORE(SDNode *N) {
2253822588
StoreSDNode *ST = cast<StoreSDNode>(N);
2253922589
SDValue Chain = ST->getChain();
@@ -22768,6 +22818,9 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
2276822818
if (SDValue NewSt = splitMergedValStore(ST))
2276922819
return NewSt;
2277022820

22821+
if (SDValue MaskedStore = foldToMaskedStore(ST, DAG, SDLoc(N)))
22822+
return MaskedStore;
22823+
2277122824
return ReduceLoadOpStoreWidth(N);
2277222825
}
2277322826

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,8 @@ void TargetLoweringBase::initActions() {
905905
setOperationAction(ISD::GET_FPENV, VT, Expand);
906906
setOperationAction(ISD::SET_FPENV, VT, Expand);
907907
setOperationAction(ISD::RESET_FPENV, VT, Expand);
908+
909+
setOperationAction(ISD::MSTORE, VT, Expand);
908910
}
909911

910912
// Most targets ignore the @llvm.prefetch intrinsic.

0 commit comments

Comments
 (0)