@@ -17773,11 +17773,19 @@ static bool flatInstrMayAccessPrivate(const Instruction *I) {
1777317773 !AMDGPU::hasValueInRangeLikeMetadata(*MD, AMDGPUAS::PRIVATE_ADDRESS);
1777417774}
1777517775
17776+ static TargetLowering::AtomicExpansionKind
17777+ getPrivateAtomicExpansionKind(const GCNSubtarget &STI) {
17778+ // For GAS, lower to flat atomic.
17779+ return STI.hasGloballyAddressableScratch()
17780+ ? TargetLowering::AtomicExpansionKind::CustomExpand
17781+ : TargetLowering::AtomicExpansionKind::NotAtomic;
17782+ }
17783+
1777617784TargetLowering::AtomicExpansionKind
1777717785SITargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
1777817786 unsigned AS = RMW->getPointerAddressSpace();
1777917787 if (AS == AMDGPUAS::PRIVATE_ADDRESS)
17780- return AtomicExpansionKind::NotAtomic ;
17788+ return getPrivateAtomicExpansionKind(*getSubtarget()) ;
1778117789
1778217790 // 64-bit flat atomics that dynamically reside in private memory will silently
1778317791 // be dropped.
@@ -18048,22 +18056,22 @@ SITargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const {
1804818056TargetLowering::AtomicExpansionKind
1804918057SITargetLowering::shouldExpandAtomicLoadInIR(LoadInst *LI) const {
1805018058 return LI->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS
18051- ? AtomicExpansionKind::NotAtomic
18059+ ? getPrivateAtomicExpansionKind(*getSubtarget())
1805218060 : AtomicExpansionKind::None;
1805318061}
1805418062
1805518063TargetLowering::AtomicExpansionKind
1805618064SITargetLowering::shouldExpandAtomicStoreInIR(StoreInst *SI) const {
1805718065 return SI->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS
18058- ? AtomicExpansionKind::NotAtomic
18066+ ? getPrivateAtomicExpansionKind(*getSubtarget())
1805918067 : AtomicExpansionKind::None;
1806018068}
1806118069
1806218070TargetLowering::AtomicExpansionKind
1806318071SITargetLowering::shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CmpX) const {
1806418072 unsigned AddrSpace = CmpX->getPointerAddressSpace();
1806518073 if (AddrSpace == AMDGPUAS::PRIVATE_ADDRESS)
18066- return AtomicExpansionKind::NotAtomic ;
18074+ return getPrivateAtomicExpansionKind(*getSubtarget()) ;
1806718075
1806818076 if (AddrSpace != AMDGPUAS::FLAT_ADDRESS || !flatInstrMayAccessPrivate(CmpX))
1806918077 return AtomicExpansionKind::None;
@@ -18433,9 +18441,24 @@ void SITargetLowering::emitExpandAtomicAddrSpacePredicate(
1843318441 Builder.CreateBr(ExitBB);
1843418442}
1843518443
18444+ static void convertScratchAtomicToFlatAtomic(Instruction *I,
18445+ unsigned PtrOpIdx) {
18446+ Value *PtrOp = I->getOperand(PtrOpIdx);
18447+ assert(PtrOp->getType()->getPointerAddressSpace() ==
18448+ AMDGPUAS::PRIVATE_ADDRESS);
18449+
18450+ Type *FlatPtr = PointerType::get(I->getContext(), AMDGPUAS::FLAT_ADDRESS);
18451+ Value *ASCast = CastInst::CreatePointerCast(PtrOp, FlatPtr, "scratch.ascast",
18452+ I->getIterator());
18453+ I->setOperand(PtrOpIdx, ASCast);
18454+ }
18455+
1843618456void SITargetLowering::emitExpandAtomicRMW(AtomicRMWInst *AI) const {
1843718457 AtomicRMWInst::BinOp Op = AI->getOperation();
1843818458
18459+ if (AI->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS)
18460+ return convertScratchAtomicToFlatAtomic(AI, AI->getPointerOperandIndex());
18461+
1843918462 if (Op == AtomicRMWInst::Sub || Op == AtomicRMWInst::Or ||
1844018463 Op == AtomicRMWInst::Xor) {
1844118464 if (const auto *ConstVal = dyn_cast<Constant>(AI->getValOperand());
@@ -18458,9 +18481,28 @@ void SITargetLowering::emitExpandAtomicRMW(AtomicRMWInst *AI) const {
1845818481}
1845918482
1846018483void SITargetLowering::emitExpandAtomicCmpXchg(AtomicCmpXchgInst *CI) const {
18484+ if (CI->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS)
18485+ return convertScratchAtomicToFlatAtomic(CI, CI->getPointerOperandIndex());
18486+
1846118487 emitExpandAtomicAddrSpacePredicate(CI);
1846218488}
1846318489
18490+ void SITargetLowering::emitExpandAtomicLoad(LoadInst *LI) const {
18491+ if (LI->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS)
18492+ return convertScratchAtomicToFlatAtomic(LI, LI->getPointerOperandIndex());
18493+
18494+ llvm_unreachable(
18495+ "Expand Atomic Load only handles SCRATCH -> FLAT conversion");
18496+ }
18497+
18498+ void SITargetLowering::emitExpandAtomicStore(StoreInst *SI) const {
18499+ if (SI->getPointerAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS)
18500+ return convertScratchAtomicToFlatAtomic(SI, SI->getPointerOperandIndex());
18501+
18502+ llvm_unreachable(
18503+ "Expand Atomic Store only handles SCRATCH -> FLAT conversion");
18504+ }
18505+
1846418506LoadInst *
1846518507SITargetLowering::lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *AI) const {
1846618508 IRBuilder<> Builder(AI);
0 commit comments