Skip to content

Commit 88a8594

Browse files
authored
AMDGPU: Directly handle all atomicrmw cases in SIISelLowering (#102439)
1 parent 7ea7864 commit 88a8594

File tree

4 files changed

+85
-37
lines changed

4 files changed

+85
-37
lines changed

llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5999,34 +5999,6 @@ bool AMDGPUTargetLowering::isReassocProfitable(MachineRegisterInfo &MRI,
59995999
return MRI.hasOneNonDBGUse(N0); // FIXME: handle regbanks
60006000
}
60016001

6002-
TargetLowering::AtomicExpansionKind
6003-
AMDGPUTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
6004-
switch (RMW->getOperation()) {
6005-
case AtomicRMWInst::Nand:
6006-
case AtomicRMWInst::FAdd:
6007-
case AtomicRMWInst::FSub:
6008-
case AtomicRMWInst::FMax:
6009-
case AtomicRMWInst::FMin:
6010-
return AtomicExpansionKind::CmpXChg;
6011-
case AtomicRMWInst::Xchg: {
6012-
const DataLayout &DL = RMW->getFunction()->getDataLayout();
6013-
unsigned ValSize = DL.getTypeSizeInBits(RMW->getType());
6014-
if (ValSize == 32 || ValSize == 64)
6015-
return AtomicExpansionKind::None;
6016-
return AtomicExpansionKind::CmpXChg;
6017-
}
6018-
default: {
6019-
if (auto *IntTy = dyn_cast<IntegerType>(RMW->getType())) {
6020-
unsigned Size = IntTy->getBitWidth();
6021-
if (Size == 32 || Size == 64)
6022-
return AtomicExpansionKind::None;
6023-
}
6024-
6025-
return AtomicExpansionKind::CmpXChg;
6026-
}
6027-
}
6028-
}
6029-
60306002
/// Whether it is profitable to sink the operands of an
60316003
/// Instruction I to the basic block of I.
60326004
/// This helps using several modifiers (like abs and neg) more often.

llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,6 @@ class AMDGPUTargetLowering : public TargetLowering {
388388
return MVT::i32;
389389
}
390390

391-
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *) const override;
392-
393391
bool shouldSinkOperands(Instruction *I,
394392
SmallVectorImpl<Use *> &Ops) const override;
395393
};

llvm/lib/Target/AMDGPU/R600ISelLowering.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,14 +2175,33 @@ SDNode *R600TargetLowering::PostISelFolding(MachineSDNode *Node,
21752175
TargetLowering::AtomicExpansionKind
21762176
R600TargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
21772177
switch (RMW->getOperation()) {
2178+
case AtomicRMWInst::Nand:
2179+
case AtomicRMWInst::FAdd:
2180+
case AtomicRMWInst::FSub:
2181+
case AtomicRMWInst::FMax:
2182+
case AtomicRMWInst::FMin:
2183+
return AtomicExpansionKind::CmpXChg;
21782184
case AtomicRMWInst::UIncWrap:
21792185
case AtomicRMWInst::UDecWrap:
21802186
// FIXME: Cayman at least appears to have instructions for this, but the
21812187
// instruction defintions appear to be missing.
21822188
return AtomicExpansionKind::CmpXChg;
2189+
case AtomicRMWInst::Xchg: {
2190+
const DataLayout &DL = RMW->getFunction()->getDataLayout();
2191+
unsigned ValSize = DL.getTypeSizeInBits(RMW->getType());
2192+
if (ValSize == 32 || ValSize == 64)
2193+
return AtomicExpansionKind::None;
2194+
return AtomicExpansionKind::CmpXChg;
2195+
}
21832196
default:
2184-
break;
2197+
if (auto *IntTy = dyn_cast<IntegerType>(RMW->getType())) {
2198+
unsigned Size = IntTy->getBitWidth();
2199+
if (Size == 32 || Size == 64)
2200+
return AtomicExpansionKind::None;
2201+
}
2202+
2203+
return AtomicExpansionKind::CmpXChg;
21852204
}
21862205

2187-
return AMDGPUTargetLowering::shouldExpandAtomicRMWInIR(RMW);
2206+
llvm_unreachable("covered atomicrmw op switch");
21882207
}

llvm/lib/Target/AMDGPU/SIISelLowering.cpp

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16114,6 +16114,39 @@ static bool isBFloat2(Type *Ty) {
1611416114
return VT && VT->getNumElements() == 2 && VT->getElementType()->isBFloatTy();
1611516115
}
1611616116

16117+
/// \return true if atomicrmw integer ops work for the type.
16118+
static bool isAtomicRMWLegalIntTy(Type *Ty) {
16119+
if (auto *IT = dyn_cast<IntegerType>(Ty)) {
16120+
unsigned BW = IT->getBitWidth();
16121+
return BW == 32 || BW == 64;
16122+
}
16123+
16124+
return false;
16125+
}
16126+
16127+
/// \return true if this atomicrmw xchg type can be selected.
16128+
static bool isAtomicRMWLegalXChgTy(const AtomicRMWInst *RMW) {
16129+
Type *Ty = RMW->getType();
16130+
if (isAtomicRMWLegalIntTy(Ty))
16131+
return true;
16132+
16133+
if (PointerType *PT = dyn_cast<PointerType>(Ty)) {
16134+
const DataLayout &DL = RMW->getFunction()->getParent()->getDataLayout();
16135+
unsigned BW = DL.getPointerSizeInBits(PT->getAddressSpace());
16136+
return BW == 32 || BW == 64;
16137+
}
16138+
16139+
if (Ty->isFloatTy() || Ty->isDoubleTy())
16140+
return true;
16141+
16142+
if (FixedVectorType *VT = dyn_cast<FixedVectorType>(Ty)) {
16143+
return VT->getNumElements() == 2 &&
16144+
VT->getElementType()->getPrimitiveSizeInBits() == 16;
16145+
}
16146+
16147+
return false;
16148+
}
16149+
1611716150
/// \returns true if it's valid to emit a native instruction for \p RMW, based
1611816151
/// on the properties of the target memory.
1611916152
static bool globalMemoryFPAtomicIsLegal(const GCNSubtarget &Subtarget,
@@ -16142,6 +16175,14 @@ static bool globalMemoryFPAtomicIsLegal(const GCNSubtarget &Subtarget,
1614216175
.getValueAsBool();
1614316176
}
1614416177

16178+
/// \return Action to perform on AtomicRMWInsts for integer operations.
16179+
static TargetLowering::AtomicExpansionKind
16180+
atomicSupportedIfLegalIntType(const AtomicRMWInst *RMW) {
16181+
return isAtomicRMWLegalIntTy(RMW->getType())
16182+
? TargetLowering::AtomicExpansionKind::None
16183+
: TargetLowering::AtomicExpansionKind::CmpXChg;
16184+
}
16185+
1614516186
TargetLowering::AtomicExpansionKind
1614616187
SITargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
1614716188
unsigned AS = RMW->getPointerAddressSpace();
@@ -16161,7 +16202,22 @@ SITargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
1616116202
SSID == SyncScope::System ||
1616216203
SSID == RMW->getContext().getOrInsertSyncScopeID("one-as");
1616316204

16164-
switch (RMW->getOperation()) {
16205+
auto Op = RMW->getOperation();
16206+
switch (Op) {
16207+
case AtomicRMWInst::Xchg: {
16208+
// PCIe supports add and xchg for system atomics.
16209+
return isAtomicRMWLegalXChgTy(RMW)
16210+
? TargetLowering::AtomicExpansionKind::None
16211+
: TargetLowering::AtomicExpansionKind::CmpXChg;
16212+
16213+
// PCIe supports add and xchg for system atomics.
16214+
return atomicSupportedIfLegalIntType(RMW);
16215+
}
16216+
case AtomicRMWInst::Add:
16217+
case AtomicRMWInst::And:
16218+
case AtomicRMWInst::UIncWrap:
16219+
case AtomicRMWInst::UDecWrap:
16220+
return atomicSupportedIfLegalIntType(RMW);
1616516221
case AtomicRMWInst::Sub:
1616616222
case AtomicRMWInst::Or:
1616716223
case AtomicRMWInst::Xor: {
@@ -16173,7 +16229,7 @@ SITargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
1617316229
return AtomicExpansionKind::Expand;
1617416230
}
1617516231

16176-
break;
16232+
return atomicSupportedIfLegalIntType(RMW);
1617716233
}
1617816234
case AtomicRMWInst::FAdd: {
1617916235
Type *Ty = RMW->getType();
@@ -16335,13 +16391,16 @@ SITargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
1633516391
if (HasSystemScope)
1633616392
return AtomicExpansionKind::CmpXChg;
1633716393
}
16338-
break;
16394+
16395+
return atomicSupportedIfLegalIntType(RMW);
1633916396
}
16397+
case AtomicRMWInst::Nand:
16398+
case AtomicRMWInst::FSub:
1634016399
default:
16341-
break;
16400+
return AtomicExpansionKind::CmpXChg;
1634216401
}
1634316402

16344-
return AMDGPUTargetLowering::shouldExpandAtomicRMWInIR(RMW);
16403+
llvm_unreachable("covered atomicrmw op switch");
1634516404
}
1634616405

1634716406
TargetLowering::AtomicExpansionKind

0 commit comments

Comments
 (0)