@@ -98,7 +98,7 @@ class AtomicExpandImpl {
9898 IRBuilderBase &Builder, Type *ResultType, Value *Addr, Align AddrAlign,
9999 AtomicOrdering MemOpOrder, SyncScope::ID SSID,
100100 function_ref<Value *(IRBuilderBase &, Value *)> PerformOp,
101- CreateCmpXchgInstFun CreateCmpXchg);
101+ CreateCmpXchgInstFun CreateCmpXchg, Instruction *MetadataSrc );
102102 bool tryExpandAtomicCmpXchg (AtomicCmpXchgInst *CI);
103103
104104 bool expandAtomicCmpXchg (AtomicCmpXchgInst *CI);
@@ -194,6 +194,39 @@ static unsigned getAtomicOpSize(AtomicCmpXchgInst *CASI) {
194194 return DL.getTypeStoreSize (CASI->getCompareOperand ()->getType ());
195195}
196196
197+ // / Copy metadata that's safe to preserve when widening atomics.
198+ static void copyMetadataForAtomic (Instruction &Dest,
199+ const Instruction &Source) {
200+ SmallVector<std::pair<unsigned , MDNode *>, 8 > MD;
201+ Source.getAllMetadata (MD);
202+ LLVMContext &Ctx = Dest.getContext ();
203+ MDBuilder MDB (Ctx);
204+
205+ for (auto [ID, N] : MD) {
206+ switch (ID) {
207+ case LLVMContext::MD_dbg:
208+ case LLVMContext::MD_tbaa:
209+ case LLVMContext::MD_tbaa_struct:
210+ case LLVMContext::MD_alias_scope:
211+ case LLVMContext::MD_noalias:
212+ case LLVMContext::MD_noalias_addrspace:
213+ case LLVMContext::MD_access_group:
214+ case LLVMContext::MD_mmra:
215+ Dest.setMetadata (ID, N);
216+ break ;
217+ default :
218+ if (ID == Ctx.getMDKindID (" amdgpu.no.remote.memory" ))
219+ Dest.setMetadata (ID, N);
220+ else if (ID == Ctx.getMDKindID (" amdgpu.no.fine.grained.memory" ))
221+ Dest.setMetadata (ID, N);
222+
223+ // Losing amdgpu.ignore.denormal.mode, but it doesn't matter for current
224+ // uses.
225+ break ;
226+ }
227+ }
228+ }
229+
197230// Determine if a particular atomic operation has a supported size,
198231// and is of appropriate alignment, to be passed through for target
199232// lowering. (Versus turning into a __atomic libcall)
@@ -600,7 +633,8 @@ void AtomicExpandImpl::expandAtomicStore(StoreInst *SI) {
600633static void createCmpXchgInstFun (IRBuilderBase &Builder, Value *Addr,
601634 Value *Loaded, Value *NewVal, Align AddrAlign,
602635 AtomicOrdering MemOpOrder, SyncScope::ID SSID,
603- Value *&Success, Value *&NewLoaded) {
636+ Value *&Success, Value *&NewLoaded,
637+ Instruction *MetadataSrc) {
604638 Type *OrigTy = NewVal->getType ();
605639
606640 // This code can go away when cmpxchg supports FP and vector types.
@@ -612,9 +646,12 @@ static void createCmpXchgInstFun(IRBuilderBase &Builder, Value *Addr,
612646 Loaded = Builder.CreateBitCast (Loaded, IntTy);
613647 }
614648
615- Value *Pair = Builder.CreateAtomicCmpXchg (
649+ AtomicCmpXchgInst *Pair = Builder.CreateAtomicCmpXchg (
616650 Addr, Loaded, NewVal, AddrAlign, MemOpOrder,
617651 AtomicCmpXchgInst::getStrongestFailureOrdering (MemOpOrder), SSID);
652+ if (MetadataSrc)
653+ copyMetadataForAtomic (*Pair, *MetadataSrc);
654+
618655 Success = Builder.CreateExtractValue (Pair, 1 , " success" );
619656 NewLoaded = Builder.CreateExtractValue (Pair, 0 , " newloaded" );
620657
@@ -951,9 +988,9 @@ void AtomicExpandImpl::expandPartwordAtomicRMW(
951988
952989 Value *OldResult;
953990 if (ExpansionKind == TargetLoweringBase::AtomicExpansionKind::CmpXChg) {
954- OldResult = insertRMWCmpXchgLoop (Builder, PMV. WordType , PMV. AlignedAddr ,
955- PMV.AlignedAddrAlignment , MemOpOrder, SSID ,
956- PerformPartwordOp, createCmpXchgInstFun);
991+ OldResult = insertRMWCmpXchgLoop (
992+ Builder, PMV.WordType , PMV. AlignedAddr , PMV. AlignedAddrAlignment ,
993+ MemOpOrder, SSID, PerformPartwordOp, createCmpXchgInstFun, AI );
957994 } else {
958995 assert (ExpansionKind == TargetLoweringBase::AtomicExpansionKind::LLSC);
959996 OldResult = insertRMWLLSCLoop (Builder, PMV.WordType , PMV.AlignedAddr ,
@@ -966,36 +1003,6 @@ void AtomicExpandImpl::expandPartwordAtomicRMW(
9661003 AI->eraseFromParent ();
9671004}
9681005
969- // / Copy metadata that's safe to preserve when widening atomics.
970- static void copyMetadataForAtomic (Instruction &Dest,
971- const Instruction &Source) {
972- SmallVector<std::pair<unsigned , MDNode *>, 8 > MD;
973- Source.getAllMetadata (MD);
974- LLVMContext &Ctx = Dest.getContext ();
975- MDBuilder MDB (Ctx);
976-
977- for (auto [ID, N] : MD) {
978- switch (ID) {
979- case LLVMContext::MD_dbg:
980- case LLVMContext::MD_tbaa:
981- case LLVMContext::MD_tbaa_struct:
982- case LLVMContext::MD_alias_scope:
983- case LLVMContext::MD_noalias:
984- case LLVMContext::MD_access_group:
985- case LLVMContext::MD_mmra:
986- Dest.setMetadata (ID, N);
987- break ;
988- default :
989- if (ID == Ctx.getMDKindID (" amdgpu.no.remote.memory" ))
990- Dest.setMetadata (ID, N);
991- else if (ID == Ctx.getMDKindID (" amdgpu.no.fine.grained.memory" ))
992- Dest.setMetadata (ID, N);
993-
994- break ;
995- }
996- }
997- }
998-
9991006// Widen the bitwise atomicrmw (or/xor/and) to the minimum supported width.
10001007AtomicRMWInst *AtomicExpandImpl::widenPartwordAtomicRMW (AtomicRMWInst *AI) {
10011008 ReplacementIRBuilder Builder (AI, *DL);
@@ -1591,7 +1598,7 @@ Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
15911598 IRBuilderBase &Builder, Type *ResultTy, Value *Addr, Align AddrAlign,
15921599 AtomicOrdering MemOpOrder, SyncScope::ID SSID,
15931600 function_ref<Value *(IRBuilderBase &, Value *)> PerformOp,
1594- CreateCmpXchgInstFun CreateCmpXchg) {
1601+ CreateCmpXchgInstFun CreateCmpXchg, Instruction *MetadataSrc ) {
15951602 LLVMContext &Ctx = Builder.getContext ();
15961603 BasicBlock *BB = Builder.GetInsertBlock ();
15971604 Function *F = BB->getParent ();
@@ -1637,7 +1644,7 @@ Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
16371644 MemOpOrder == AtomicOrdering::Unordered
16381645 ? AtomicOrdering::Monotonic
16391646 : MemOpOrder,
1640- SSID, Success, NewLoaded);
1647+ SSID, Success, NewLoaded, MetadataSrc );
16411648 assert (Success && NewLoaded);
16421649
16431650 Loaded->addIncoming (NewLoaded, LoopBB);
@@ -1686,7 +1693,7 @@ bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI,
16861693 return buildAtomicRMWValue (AI->getOperation (), Builder, Loaded,
16871694 AI->getValOperand ());
16881695 },
1689- CreateCmpXchg);
1696+ CreateCmpXchg, /* MetadataSrc= */ AI );
16901697
16911698 AI->replaceAllUsesWith (Loaded);
16921699 AI->eraseFromParent ();
@@ -1838,11 +1845,15 @@ void AtomicExpandImpl::expandAtomicRMWToLibcall(AtomicRMWInst *I) {
18381845 expandAtomicRMWToCmpXchg (
18391846 I, [this ](IRBuilderBase &Builder, Value *Addr, Value *Loaded,
18401847 Value *NewVal, Align Alignment, AtomicOrdering MemOpOrder,
1841- SyncScope::ID SSID, Value *&Success, Value *&NewLoaded) {
1848+ SyncScope::ID SSID, Value *&Success, Value *&NewLoaded,
1849+ Instruction *MetadataSrc) {
18421850 // Create the CAS instruction normally...
18431851 AtomicCmpXchgInst *Pair = Builder.CreateAtomicCmpXchg (
18441852 Addr, Loaded, NewVal, Alignment, MemOpOrder,
18451853 AtomicCmpXchgInst::getStrongestFailureOrdering (MemOpOrder), SSID);
1854+ if (MetadataSrc)
1855+ copyMetadataForAtomic (*Pair, *MetadataSrc);
1856+
18461857 Success = Builder.CreateExtractValue (Pair, 1 , " success" );
18471858 NewLoaded = Builder.CreateExtractValue (Pair, 0 , " newloaded" );
18481859
0 commit comments