Skip to content

Commit 500dc8a

Browse files
committed
AtomicExpand: Copy metadata from atomicrmw to cmpxchg
When expanding an atomicrmw with a cmpxchg, preserve any metadata attached to it. This will avoid unwanted double expansions in a future commit. The initial load should also probably receive the same metadata (which for some reason is not emitted as an atomic).
1 parent f85fb78 commit 500dc8a

20 files changed

+1080
-1027
lines changed

llvm/include/llvm/CodeGen/AtomicExpandUtils.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ class Value;
2020

2121
/// Parameters (see the expansion example below):
2222
/// (the builder, %addr, %loaded, %new_val, ordering,
23-
/// /* OUT */ %success, /* OUT */ %new_loaded)
24-
using CreateCmpXchgInstFun =
25-
function_ref<void(IRBuilderBase &, Value *, Value *, Value *, Align,
26-
AtomicOrdering, SyncScope::ID, Value *&, Value *&)>;
23+
/// /* OUT */ %success, /* OUT */ %new_loaded,
24+
/// %MetadataSrc)
25+
using CreateCmpXchgInstFun = function_ref<void(
26+
IRBuilderBase &, Value *, Value *, Value *, Align, AtomicOrdering,
27+
SyncScope::ID, Value *&, Value *&, Instruction *)>;
2728

2829
/// Expand an atomic RMW instruction into a loop utilizing
2930
/// cmpxchg. You'll want to make sure your target machine likes cmpxchg

llvm/lib/CodeGen/AtomicExpandPass.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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);
@@ -600,7 +600,8 @@ void AtomicExpandImpl::expandAtomicStore(StoreInst *SI) {
600600
static void createCmpXchgInstFun(IRBuilderBase &Builder, Value *Addr,
601601
Value *Loaded, Value *NewVal, Align AddrAlign,
602602
AtomicOrdering MemOpOrder, SyncScope::ID SSID,
603-
Value *&Success, Value *&NewLoaded) {
603+
Value *&Success, Value *&NewLoaded,
604+
Instruction *MetadataSrc) {
604605
Type *OrigTy = NewVal->getType();
605606

606607
// This code can go away when cmpxchg supports FP and vector types.
@@ -612,9 +613,12 @@ static void createCmpXchgInstFun(IRBuilderBase &Builder, Value *Addr,
612613
Loaded = Builder.CreateBitCast(Loaded, IntTy);
613614
}
614615

615-
Value *Pair = Builder.CreateAtomicCmpXchg(
616+
AtomicCmpXchgInst *Pair = Builder.CreateAtomicCmpXchg(
616617
Addr, Loaded, NewVal, AddrAlign, MemOpOrder,
617618
AtomicCmpXchgInst::getStrongestFailureOrdering(MemOpOrder), SSID);
619+
if (MetadataSrc)
620+
Pair->copyMetadata(*MetadataSrc);
621+
618622
Success = Builder.CreateExtractValue(Pair, 1, "success");
619623
NewLoaded = Builder.CreateExtractValue(Pair, 0, "newloaded");
620624

@@ -951,9 +955,9 @@ void AtomicExpandImpl::expandPartwordAtomicRMW(
951955

952956
Value *OldResult;
953957
if (ExpansionKind == TargetLoweringBase::AtomicExpansionKind::CmpXChg) {
954-
OldResult = insertRMWCmpXchgLoop(Builder, PMV.WordType, PMV.AlignedAddr,
955-
PMV.AlignedAddrAlignment, MemOpOrder, SSID,
956-
PerformPartwordOp, createCmpXchgInstFun);
958+
OldResult = insertRMWCmpXchgLoop(
959+
Builder, PMV.WordType, PMV.AlignedAddr, PMV.AlignedAddrAlignment,
960+
MemOpOrder, SSID, PerformPartwordOp, createCmpXchgInstFun, AI);
957961
} else {
958962
assert(ExpansionKind == TargetLoweringBase::AtomicExpansionKind::LLSC);
959963
OldResult = insertRMWLLSCLoop(Builder, PMV.WordType, PMV.AlignedAddr,
@@ -1591,7 +1595,7 @@ Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
15911595
IRBuilderBase &Builder, Type *ResultTy, Value *Addr, Align AddrAlign,
15921596
AtomicOrdering MemOpOrder, SyncScope::ID SSID,
15931597
function_ref<Value *(IRBuilderBase &, Value *)> PerformOp,
1594-
CreateCmpXchgInstFun CreateCmpXchg) {
1598+
CreateCmpXchgInstFun CreateCmpXchg, Instruction *MetadataSrc) {
15951599
LLVMContext &Ctx = Builder.getContext();
15961600
BasicBlock *BB = Builder.GetInsertBlock();
15971601
Function *F = BB->getParent();
@@ -1637,7 +1641,7 @@ Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
16371641
MemOpOrder == AtomicOrdering::Unordered
16381642
? AtomicOrdering::Monotonic
16391643
: MemOpOrder,
1640-
SSID, Success, NewLoaded);
1644+
SSID, Success, NewLoaded, MetadataSrc);
16411645
assert(Success && NewLoaded);
16421646

16431647
Loaded->addIncoming(NewLoaded, LoopBB);
@@ -1686,7 +1690,7 @@ bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI,
16861690
return buildAtomicRMWValue(AI->getOperation(), Builder, Loaded,
16871691
AI->getValOperand());
16881692
},
1689-
CreateCmpXchg);
1693+
CreateCmpXchg, /*MetadataSrc=*/AI);
16901694

16911695
AI->replaceAllUsesWith(Loaded);
16921696
AI->eraseFromParent();
@@ -1838,11 +1842,15 @@ void AtomicExpandImpl::expandAtomicRMWToLibcall(AtomicRMWInst *I) {
18381842
expandAtomicRMWToCmpXchg(
18391843
I, [this](IRBuilderBase &Builder, Value *Addr, Value *Loaded,
18401844
Value *NewVal, Align Alignment, AtomicOrdering MemOpOrder,
1841-
SyncScope::ID SSID, Value *&Success, Value *&NewLoaded) {
1845+
SyncScope::ID SSID, Value *&Success, Value *&NewLoaded,
1846+
Instruction *MetadataSrc) {
18421847
// Create the CAS instruction normally...
18431848
AtomicCmpXchgInst *Pair = Builder.CreateAtomicCmpXchg(
18441849
Addr, Loaded, NewVal, Alignment, MemOpOrder,
18451850
AtomicCmpXchgInst::getStrongestFailureOrdering(MemOpOrder), SSID);
1851+
if (MetadataSrc)
1852+
Pair->copyMetadata(*MetadataSrc);
1853+
18461854
Success = Builder.CreateExtractValue(Pair, 1, "success");
18471855
NewLoaded = Builder.CreateExtractValue(Pair, 0, "newloaded");
18481856

0 commit comments

Comments
 (0)