@@ -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.
1611916152static 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+
1614516186TargetLowering::AtomicExpansionKind
1614616187SITargetLowering::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
1634716406TargetLowering::AtomicExpansionKind
0 commit comments