Skip to content

Commit 94b5c11

Browse files
authored
[ISel] Move handling of atomic loads from SystemZ to DAGCombiner (NFC). (#86484)
The folding of sign/zero extensions into an atomic load by specifying an extension type is not target specific, and therefore belongs in the DAGCombiner rather than in the SystemZ backend. - Handle atomic loads similarly to regular loads by adding AtomicLoadExtActions with set/get methods. - Move SystemZ extendAtomicLoad() to DagCombiner.cpp.
1 parent e251f56 commit 94b5c11

File tree

4 files changed

+106
-33
lines changed

4 files changed

+106
-33
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,28 @@ class TargetLoweringBase {
14541454
getLoadExtAction(ExtType, ValVT, MemVT) == Custom;
14551455
}
14561456

1457+
/// Same as getLoadExtAction, but for atomic loads.
1458+
LegalizeAction getAtomicLoadExtAction(unsigned ExtType, EVT ValVT,
1459+
EVT MemVT) const {
1460+
if (ValVT.isExtended() || MemVT.isExtended()) return Expand;
1461+
unsigned ValI = (unsigned)ValVT.getSimpleVT().SimpleTy;
1462+
unsigned MemI = (unsigned)MemVT.getSimpleVT().SimpleTy;
1463+
assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValI < MVT::VALUETYPE_SIZE &&
1464+
MemI < MVT::VALUETYPE_SIZE && "Table isn't big enough!");
1465+
unsigned Shift = 4 * ExtType;
1466+
LegalizeAction Action =
1467+
(LegalizeAction)((AtomicLoadExtActions[ValI][MemI] >> Shift) & 0xf);
1468+
assert((Action == Legal || Action == Expand) &&
1469+
"Unsupported atomic load extension action.");
1470+
return Action;
1471+
}
1472+
1473+
/// Return true if the specified atomic load with extension is legal on
1474+
/// this target.
1475+
bool isAtomicLoadExtLegal(unsigned ExtType, EVT ValVT, EVT MemVT) const {
1476+
return getAtomicLoadExtAction(ExtType, ValVT, MemVT) == Legal;
1477+
}
1478+
14571479
/// Return how this store with truncation should be treated: either it is
14581480
/// legal, needs to be promoted to a larger size, needs to be expanded to some
14591481
/// other code sequence, or the target has a custom expander for it.
@@ -2536,6 +2558,30 @@ class TargetLoweringBase {
25362558
setLoadExtAction(ExtTypes, ValVT, MemVT, Action);
25372559
}
25382560

2561+
/// Let target indicate that an extending atomic load of the specified type
2562+
/// is legal.
2563+
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT,
2564+
LegalizeAction Action) {
2565+
assert(ExtType < ISD::LAST_LOADEXT_TYPE && ValVT.isValid() &&
2566+
MemVT.isValid() && "Table isn't big enough!");
2567+
assert((unsigned)Action < 0x10 && "too many bits for bitfield array");
2568+
unsigned Shift = 4 * ExtType;
2569+
AtomicLoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy] &=
2570+
~((uint16_t)0xF << Shift);
2571+
AtomicLoadExtActions[ValVT.SimpleTy][MemVT.SimpleTy] |=
2572+
((uint16_t)Action << Shift);
2573+
}
2574+
void setAtomicLoadExtAction(ArrayRef<unsigned> ExtTypes, MVT ValVT, MVT MemVT,
2575+
LegalizeAction Action) {
2576+
for (auto ExtType : ExtTypes)
2577+
setAtomicLoadExtAction(ExtType, ValVT, MemVT, Action);
2578+
}
2579+
void setAtomicLoadExtAction(ArrayRef<unsigned> ExtTypes, MVT ValVT,
2580+
ArrayRef<MVT> MemVTs, LegalizeAction Action) {
2581+
for (auto MemVT : MemVTs)
2582+
setAtomicLoadExtAction(ExtTypes, ValVT, MemVT, Action);
2583+
}
2584+
25392585
/// Indicate that the specified truncating store does not work with the
25402586
/// specified type and indicate what to do about it.
25412587
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action) {
@@ -3521,6 +3567,10 @@ class TargetLoweringBase {
35213567
/// for each of the 4 load ext types.
35223568
uint16_t LoadExtActions[MVT::VALUETYPE_SIZE][MVT::VALUETYPE_SIZE];
35233569

3570+
/// Similar to LoadExtActions, but for atomic loads. Only Legal or Expand
3571+
/// (default) values are supported.
3572+
uint16_t AtomicLoadExtActions[MVT::VALUETYPE_SIZE][MVT::VALUETYPE_SIZE];
3573+
35243574
/// For each value type pair keep a LegalizeAction that indicates whether a
35253575
/// truncating store of a specific value type and truncating type is legal.
35263576
LegalizeAction TruncStoreActions[MVT::VALUETYPE_SIZE][MVT::VALUETYPE_SIZE];

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13149,6 +13149,37 @@ tryToFoldExtOfMaskedLoad(SelectionDAG &DAG, const TargetLowering &TLI, EVT VT,
1314913149
return NewLoad;
1315013150
}
1315113151

13152+
// fold ([s|z]ext (atomic_load)) -> ([s|z]ext (truncate ([s|z]ext atomic_load)))
13153+
static SDValue tryToFoldExtOfAtomicLoad(SelectionDAG &DAG,
13154+
const TargetLowering &TLI, EVT VT,
13155+
SDValue N0,
13156+
ISD::LoadExtType ExtLoadType) {
13157+
auto *ALoad = dyn_cast<AtomicSDNode>(N0);
13158+
if (!ALoad || ALoad->getOpcode() != ISD::ATOMIC_LOAD)
13159+
return {};
13160+
EVT MemoryVT = ALoad->getMemoryVT();
13161+
if (!TLI.isAtomicLoadExtLegal(ExtLoadType, VT, MemoryVT))
13162+
return {};
13163+
// Can't fold into ALoad if it is already extending differently.
13164+
ISD::LoadExtType ALoadExtTy = ALoad->getExtensionType();
13165+
if ((ALoadExtTy == ISD::ZEXTLOAD && ExtLoadType == ISD::SEXTLOAD) ||
13166+
(ALoadExtTy == ISD::SEXTLOAD && ExtLoadType == ISD::ZEXTLOAD))
13167+
return {};
13168+
13169+
EVT OrigVT = ALoad->getValueType(0);
13170+
assert(OrigVT.getSizeInBits() < VT.getSizeInBits() && "VT should be wider.");
13171+
auto *NewALoad = cast<AtomicSDNode>(DAG.getAtomic(
13172+
ISD::ATOMIC_LOAD, SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(),
13173+
ALoad->getBasePtr(), ALoad->getMemOperand()));
13174+
NewALoad->setExtensionType(ExtLoadType);
13175+
DAG.ReplaceAllUsesOfValueWith(
13176+
SDValue(ALoad, 0),
13177+
DAG.getNode(ISD::TRUNCATE, SDLoc(ALoad), OrigVT, SDValue(NewALoad, 0)));
13178+
// Update the chain uses.
13179+
DAG.ReplaceAllUsesOfValueWith(SDValue(ALoad, 1), SDValue(NewALoad, 1));
13180+
return SDValue(NewALoad, 0);
13181+
}
13182+
1315213183
static SDValue foldExtendedSignBitTest(SDNode *N, SelectionDAG &DAG,
1315313184
bool LegalOperations) {
1315413185
assert((N->getOpcode() == ISD::SIGN_EXTEND ||
@@ -13420,6 +13451,11 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
1342013451
DAG, *this, TLI, VT, LegalOperations, N, N0, ISD::SEXTLOAD))
1342113452
return foldedExt;
1342213453

13454+
// Try to simplify (sext (atomic_load x)).
13455+
if (SDValue foldedExt =
13456+
tryToFoldExtOfAtomicLoad(DAG, TLI, VT, N0, ISD::SEXTLOAD))
13457+
return foldedExt;
13458+
1342313459
// fold (sext (and/or/xor (load x), cst)) ->
1342413460
// (and/or/xor (sextload x), (sext cst))
1342513461
if (ISD::isBitwiseLogicOp(N0.getOpcode()) &&
@@ -13731,6 +13767,11 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
1373113767
if (SDValue ExtLoad = CombineExtLoad(N))
1373213768
return ExtLoad;
1373313769

13770+
// Try to simplify (zext (atomic_load x)).
13771+
if (SDValue foldedExt =
13772+
tryToFoldExtOfAtomicLoad(DAG, TLI, VT, N0, ISD::ZEXTLOAD))
13773+
return foldedExt;
13774+
1373413775
// fold (zext (and/or/xor (load x), cst)) ->
1373513776
// (and/or/xor (zextload x), (zext cst))
1373613777
// Unless (and (load x) cst) will match as a zextload already and has

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,12 @@ void TargetLoweringBase::initActions() {
823823
std::fill(std::begin(TargetDAGCombineArray),
824824
std::end(TargetDAGCombineArray), 0);
825825

826+
// Let extending atomic loads be unsupported by default.
827+
for (MVT ValVT : MVT::all_valuetypes())
828+
for (MVT MemVT : MVT::all_valuetypes())
829+
setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, ValVT, MemVT,
830+
Expand);
831+
826832
// We're somewhat special casing MVT::i2 and MVT::i4. Ideally we want to
827833
// remove this and targets should individually set these types if not legal.
828834
for (ISD::NodeType NT : enum_seq(ISD::DELETED_NODE, ISD::BUILTIN_OP_END,

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,15 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
293293
setOperationAction(ISD::ATOMIC_LOAD, MVT::i128, Custom);
294294
setOperationAction(ISD::ATOMIC_STORE, MVT::i128, Custom);
295295

296+
// Mark sign/zero extending atomic loads as legal, which will make
297+
// DAGCombiner fold extensions into atomic loads if possible.
298+
setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i64,
299+
{MVT::i8, MVT::i16, MVT::i32}, Legal);
300+
setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i32,
301+
{MVT::i8, MVT::i16}, Legal);
302+
setAtomicLoadExtAction({ISD::SEXTLOAD, ISD::ZEXTLOAD}, MVT::i16,
303+
MVT::i8, Legal);
304+
296305
// We can use the CC result of compare-and-swap to implement
297306
// the "success" result of ATOMIC_CMP_SWAP_WITH_SUCCESS.
298307
setOperationAction(ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS, MVT::i32, Custom);
@@ -6614,27 +6623,6 @@ SDValue SystemZTargetLowering::combineTruncateExtract(
66146623
return SDValue();
66156624
}
66166625

6617-
// Replace ALoad with a new ATOMIC_LOAD with a result that is extended to VT
6618-
// per ETy.
6619-
static SDValue extendAtomicLoad(AtomicSDNode *ALoad, EVT VT, SelectionDAG &DAG,
6620-
ISD::LoadExtType ETy) {
6621-
if (VT.getSizeInBits() > 64)
6622-
return SDValue();
6623-
EVT OrigVT = ALoad->getValueType(0);
6624-
assert(OrigVT.getSizeInBits() < VT.getSizeInBits() && "VT should be wider.");
6625-
EVT MemoryVT = ALoad->getMemoryVT();
6626-
auto *NewALoad = dyn_cast<AtomicSDNode>(DAG.getAtomic(
6627-
ISD::ATOMIC_LOAD, SDLoc(ALoad), MemoryVT, VT, ALoad->getChain(),
6628-
ALoad->getBasePtr(), ALoad->getMemOperand()));
6629-
NewALoad->setExtensionType(ETy);
6630-
DAG.ReplaceAllUsesOfValueWith(
6631-
SDValue(ALoad, 0),
6632-
DAG.getNode(ISD::TRUNCATE, SDLoc(ALoad), OrigVT, SDValue(NewALoad, 0)));
6633-
// Update the chain uses.
6634-
DAG.ReplaceAllUsesOfValueWith(SDValue(ALoad, 1), SDValue(NewALoad, 1));
6635-
return SDValue(NewALoad, 0);
6636-
}
6637-
66386626
SDValue SystemZTargetLowering::combineZERO_EXTEND(
66396627
SDNode *N, DAGCombinerInfo &DCI) const {
66406628
// Convert (zext (select_ccmask C1, C2)) into (select_ccmask C1', C2')
@@ -6681,12 +6669,6 @@ SDValue SystemZTargetLowering::combineZERO_EXTEND(
66816669
}
66826670
}
66836671

6684-
// Fold into ATOMIC_LOAD unless it is already sign extending.
6685-
if (auto *ALoad = dyn_cast<AtomicSDNode>(N0))
6686-
if (ALoad->getOpcode() == ISD::ATOMIC_LOAD &&
6687-
ALoad->getExtensionType() != ISD::SEXTLOAD)
6688-
return extendAtomicLoad(ALoad, VT, DAG, ISD::ZEXTLOAD);
6689-
66906672
return SDValue();
66916673
}
66926674

@@ -6739,12 +6721,6 @@ SDValue SystemZTargetLowering::combineSIGN_EXTEND(
67396721
}
67406722
}
67416723

6742-
// Fold into ATOMIC_LOAD unless it is already zero extending.
6743-
if (auto *ALoad = dyn_cast<AtomicSDNode>(N0))
6744-
if (ALoad->getOpcode() == ISD::ATOMIC_LOAD &&
6745-
ALoad->getExtensionType() != ISD::ZEXTLOAD)
6746-
return extendAtomicLoad(ALoad, VT, DAG, ISD::SEXTLOAD);
6747-
67486724
return SDValue();
67496725
}
67506726

0 commit comments

Comments
 (0)