@@ -98,7 +98,7 @@ class AtomicExpandImpl {
98
98
IRBuilderBase &Builder, Type *ResultType, Value *Addr, Align AddrAlign,
99
99
AtomicOrdering MemOpOrder, SyncScope::ID SSID,
100
100
function_ref<Value *(IRBuilderBase &, Value *)> PerformOp,
101
- CreateCmpXchgInstFun CreateCmpXchg);
101
+ CreateCmpXchgInstFun CreateCmpXchg, Instruction *MetadataSrc );
102
102
bool tryExpandAtomicCmpXchg (AtomicCmpXchgInst *CI);
103
103
104
104
bool expandAtomicCmpXchg (AtomicCmpXchgInst *CI);
@@ -194,6 +194,39 @@ static unsigned getAtomicOpSize(AtomicCmpXchgInst *CASI) {
194
194
return DL.getTypeStoreSize (CASI->getCompareOperand ()->getType ());
195
195
}
196
196
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
+
197
230
// Determine if a particular atomic operation has a supported size,
198
231
// and is of appropriate alignment, to be passed through for target
199
232
// lowering. (Versus turning into a __atomic libcall)
@@ -600,7 +633,8 @@ void AtomicExpandImpl::expandAtomicStore(StoreInst *SI) {
600
633
static void createCmpXchgInstFun (IRBuilderBase &Builder, Value *Addr,
601
634
Value *Loaded, Value *NewVal, Align AddrAlign,
602
635
AtomicOrdering MemOpOrder, SyncScope::ID SSID,
603
- Value *&Success, Value *&NewLoaded) {
636
+ Value *&Success, Value *&NewLoaded,
637
+ Instruction *MetadataSrc) {
604
638
Type *OrigTy = NewVal->getType ();
605
639
606
640
// This code can go away when cmpxchg supports FP and vector types.
@@ -612,9 +646,12 @@ static void createCmpXchgInstFun(IRBuilderBase &Builder, Value *Addr,
612
646
Loaded = Builder.CreateBitCast (Loaded, IntTy);
613
647
}
614
648
615
- Value *Pair = Builder.CreateAtomicCmpXchg (
649
+ AtomicCmpXchgInst *Pair = Builder.CreateAtomicCmpXchg (
616
650
Addr, Loaded, NewVal, AddrAlign, MemOpOrder,
617
651
AtomicCmpXchgInst::getStrongestFailureOrdering (MemOpOrder), SSID);
652
+ if (MetadataSrc)
653
+ copyMetadataForAtomic (*Pair, *MetadataSrc);
654
+
618
655
Success = Builder.CreateExtractValue (Pair, 1 , " success" );
619
656
NewLoaded = Builder.CreateExtractValue (Pair, 0 , " newloaded" );
620
657
@@ -951,9 +988,9 @@ void AtomicExpandImpl::expandPartwordAtomicRMW(
951
988
952
989
Value *OldResult;
953
990
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 );
957
994
} else {
958
995
assert (ExpansionKind == TargetLoweringBase::AtomicExpansionKind::LLSC);
959
996
OldResult = insertRMWLLSCLoop (Builder, PMV.WordType , PMV.AlignedAddr ,
@@ -966,36 +1003,6 @@ void AtomicExpandImpl::expandPartwordAtomicRMW(
966
1003
AI->eraseFromParent ();
967
1004
}
968
1005
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
-
999
1006
// Widen the bitwise atomicrmw (or/xor/and) to the minimum supported width.
1000
1007
AtomicRMWInst *AtomicExpandImpl::widenPartwordAtomicRMW (AtomicRMWInst *AI) {
1001
1008
ReplacementIRBuilder Builder (AI, *DL);
@@ -1591,7 +1598,7 @@ Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
1591
1598
IRBuilderBase &Builder, Type *ResultTy, Value *Addr, Align AddrAlign,
1592
1599
AtomicOrdering MemOpOrder, SyncScope::ID SSID,
1593
1600
function_ref<Value *(IRBuilderBase &, Value *)> PerformOp,
1594
- CreateCmpXchgInstFun CreateCmpXchg) {
1601
+ CreateCmpXchgInstFun CreateCmpXchg, Instruction *MetadataSrc ) {
1595
1602
LLVMContext &Ctx = Builder.getContext ();
1596
1603
BasicBlock *BB = Builder.GetInsertBlock ();
1597
1604
Function *F = BB->getParent ();
@@ -1637,7 +1644,7 @@ Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
1637
1644
MemOpOrder == AtomicOrdering::Unordered
1638
1645
? AtomicOrdering::Monotonic
1639
1646
: MemOpOrder,
1640
- SSID, Success, NewLoaded);
1647
+ SSID, Success, NewLoaded, MetadataSrc );
1641
1648
assert (Success && NewLoaded);
1642
1649
1643
1650
Loaded->addIncoming (NewLoaded, LoopBB);
@@ -1686,7 +1693,7 @@ bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI,
1686
1693
return buildAtomicRMWValue (AI->getOperation (), Builder, Loaded,
1687
1694
AI->getValOperand ());
1688
1695
},
1689
- CreateCmpXchg);
1696
+ CreateCmpXchg, /* MetadataSrc= */ AI );
1690
1697
1691
1698
AI->replaceAllUsesWith (Loaded);
1692
1699
AI->eraseFromParent ();
@@ -1838,11 +1845,15 @@ void AtomicExpandImpl::expandAtomicRMWToLibcall(AtomicRMWInst *I) {
1838
1845
expandAtomicRMWToCmpXchg (
1839
1846
I, [this ](IRBuilderBase &Builder, Value *Addr, Value *Loaded,
1840
1847
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) {
1842
1850
// Create the CAS instruction normally...
1843
1851
AtomicCmpXchgInst *Pair = Builder.CreateAtomicCmpXchg (
1844
1852
Addr, Loaded, NewVal, Alignment, MemOpOrder,
1845
1853
AtomicCmpXchgInst::getStrongestFailureOrdering (MemOpOrder), SSID);
1854
+ if (MetadataSrc)
1855
+ copyMetadataForAtomic (*Pair, *MetadataSrc);
1856
+
1846
1857
Success = Builder.CreateExtractValue (Pair, 1 , " success" );
1847
1858
NewLoaded = Builder.CreateExtractValue (Pair, 0 , " newloaded" );
1848
1859
0 commit comments