[llvm] [AtomicExpand] Preserve AA metadata when rewriting atomic operations (PR #206418)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 9 02:41:25 PDT 2026


https://github.com/ayrai-gb updated https://github.com/llvm/llvm-project/pull/206418

>From a112c723153bb4120af715d9bd367ca666fd513c Mon Sep 17 00:00:00 2001
From: Ayush Rai <your-email at amd.com>
Date: Mon, 29 Jun 2026 11:30:03 +0530
Subject: [PATCH 1/3] [AtomicExpand] Preserve AA metadata in
 expandPartwordCmpXchg

---
 llvm/lib/CodeGen/AtomicExpandPass.cpp         |  2 ++
 .../partword-cmpxchg-preserve-metadata.ll     | 22 +++++++++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 llvm/test/Transforms/AtomicExpand/AMDGPU/partword-cmpxchg-preserve-metadata.ll

diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index 059c0d5cb7b8b..fc34760f36532 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -1251,6 +1251,7 @@ bool AtomicExpandImpl::expandPartwordCmpXchg(AtomicCmpXchgInst *CI) {
   // addIncoming is done first so that any replaceAllUsesWith calls during
   // normalization correctly update the PHI incoming value.
   InitLoaded->setVolatile(CI->isVolatile());
+  copyMetadataForAtomic(*InitLoaded, *CI);
   if (TLI->shouldIssueAtomicLoadForAtomicEmulationLoop()) {
     InitLoaded->setAtomic(AtomicOrdering::Monotonic, CI->getSyncScopeID());
     // The newly created load might need to be lowered further. Because it is
@@ -1272,6 +1273,7 @@ bool AtomicExpandImpl::expandPartwordCmpXchg(AtomicCmpXchgInst *CI) {
   // expecting the underlying cmpxchg to be a machine instruction,
   // which is strong anyways.
   NewCI->setWeak(CI->isWeak());
+  copyMetadataForAtomic(*NewCI, *CI);
 
   Value *OldVal = Builder.CreateExtractValue(NewCI, 0);
   Value *Success = Builder.CreateExtractValue(NewCI, 1);
diff --git a/llvm/test/Transforms/AtomicExpand/AMDGPU/partword-cmpxchg-preserve-metadata.ll b/llvm/test/Transforms/AtomicExpand/AMDGPU/partword-cmpxchg-preserve-metadata.ll
new file mode 100644
index 0000000000000..5bbb04a555129
--- /dev/null
+++ b/llvm/test/Transforms/AtomicExpand/AMDGPU/partword-cmpxchg-preserve-metadata.ll
@@ -0,0 +1,22 @@
+; RUN: opt -mtriple=amdgcn-amd-amdhsa -S -passes='require<libcall-lowering-info>,atomic-expand' %s | FileCheck %s
+
+; A sub-word (i16) cmpxchg is widened to a word-sized cmpxchg retry loop by
+; expandPartwordCmpXchg. Both the seed load (InitLoaded) and the widened cmpxchg
+; must preserve the original !tbaa/!noalias metadata, matching the sibling
+; widenPartwordAtomicRMW path.
+
+define { i16, i1 } @test_cmpxchg_i16_preserves_metadata(ptr %p, i16 %cmp, i16 %new) {
+; CHECK-LABEL: @test_cmpxchg_i16_preserves_metadata(
+; CHECK:         load i32, ptr {{%.*}}, align 4{{.*}}!tbaa ![[TBAA:[0-9]+]]{{.*}}!noalias ![[NOALIAS:[0-9]+]]
+; CHECK:         cmpxchg ptr {{%.*}} seq_cst seq_cst, align 4{{.*}}!tbaa ![[TBAA]]{{.*}}!noalias ![[NOALIAS]]
+  %r = cmpxchg ptr %p, i16 %cmp, i16 %new seq_cst seq_cst, align 2, !tbaa !2, !noalias !6
+  ret { i16, i1 } %r
+}
+
+!0 = !{!"alias-domain"}
+!1 = !{!"alias-scope-a", !0}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"int", !4, i64 0}
+!4 = !{!"omnipotent char", !5, i64 0}
+!5 = !{!"Simple C/C++ TBAA"}
+!6 = !{!1}

>From e5dcd198b3d6bd49d093cd1dec88d04f70f8827e Mon Sep 17 00:00:00 2001
From: Ayush Rai <your-email at amd.com>
Date: Mon, 29 Jun 2026 12:12:17 +0530
Subject: [PATCH 2/3] [AtomicExpand] Preserve AA metadata when casting atomics
 to integer

---
 llvm/lib/CodeGen/AtomicExpandPass.cpp         |  4 ++
 ...tomic-cast-to-integer-preserve-metadata.ll | 46 +++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 llvm/test/Transforms/AtomicExpand/X86/atomic-cast-to-integer-preserve-metadata.ll

diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index fc34760f36532..5ebbe1172f439 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -567,6 +567,7 @@ LoadInst *AtomicExpandImpl::convertAtomicLoadToIntegerType(LoadInst *LI) {
   NewLI->setAlignment(LI->getAlign());
   NewLI->setVolatile(LI->isVolatile());
   NewLI->setAtomic(LI->getOrdering(), LI->getSyncScopeID());
+  copyMetadataForAtomic(*NewLI, *LI);
   LLVM_DEBUG(dbgs() << "Replaced " << *LI << " with " << *NewLI << "\n");
 
   Value *NewVal = LI->getType()->isPtrOrPtrVectorTy()
@@ -690,6 +691,7 @@ bool AtomicExpandImpl::expandAtomicLoadToCmpXchg(LoadInst *LI) {
       AtomicCmpXchgInst::getStrongestFailureOrdering(Order),
       LI->getSyncScopeID());
   Pair->setVolatile(LI->isVolatile());
+  copyMetadataForAtomic(*Pair, *LI);
   Value *Loaded = Builder.CreateExtractValue(Pair, 0, "loaded");
   if (NeedBitcast)
     Loaded = Builder.CreateBitCast(Loaded, Ty);
@@ -723,6 +725,7 @@ StoreInst *AtomicExpandImpl::convertAtomicStoreToIntegerType(StoreInst *SI) {
   NewSI->setAlignment(SI->getAlign());
   NewSI->setVolatile(SI->isVolatile());
   NewSI->setAtomic(SI->getOrdering(), SI->getSyncScopeID());
+  copyMetadataForAtomic(*NewSI, *SI);
   LLVM_DEBUG(dbgs() << "Replaced " << *SI << " with " << *NewSI << "\n");
   SI->eraseFromParent();
   return NewSI;
@@ -1452,6 +1455,7 @@ AtomicExpandImpl::convertCmpXchgToIntegerType(AtomicCmpXchgInst *CI) {
       CI->getFailureOrdering(), CI->getSyncScopeID());
   NewCI->setVolatile(CI->isVolatile());
   NewCI->setWeak(CI->isWeak());
+  copyMetadataForAtomic(*NewCI, *CI);
   LLVM_DEBUG(dbgs() << "Replaced " << *CI << " with " << *NewCI << "\n");
 
   Value *OldVal = Builder.CreateExtractValue(NewCI, 0);
diff --git a/llvm/test/Transforms/AtomicExpand/X86/atomic-cast-to-integer-preserve-metadata.ll b/llvm/test/Transforms/AtomicExpand/X86/atomic-cast-to-integer-preserve-metadata.ll
new file mode 100644
index 0000000000000..8564a0f73f08b
--- /dev/null
+++ b/llvm/test/Transforms/AtomicExpand/X86/atomic-cast-to-integer-preserve-metadata.ll
@@ -0,0 +1,46 @@
+; RUN: opt -S %s -passes='require<libcall-lowering-info>,atomic-expand' -mtriple=x86_64-linux-gnu | FileCheck %s
+; RUN: opt -S %s -passes='require<libcall-lowering-info>,atomic-expand' -mtriple=x86_64-linux-gnu -mattr=+cx16 | FileCheck %s --check-prefixes=CHECK,CX16
+
+; AtomicExpand casts float/vector/pointer atomics to integer atomics so the
+; backend can select them. The cast must preserve the original !tbaa/!noalias
+; metadata, matching the sibling convertAtomicXchgToIntegerType.
+
+; convertAtomicLoadToIntegerType
+define float @castload(ptr %p) {
+; CHECK-LABEL: define float @castload(
+; CHECK:    load atomic i32, ptr {{%.*}} seq_cst, align 4, !tbaa ![[TBAA:[0-9]+]], !noalias ![[NOALIAS:[0-9]+]]
+  %r = load atomic float, ptr %p seq_cst, align 4, !tbaa !2, !noalias !6
+  ret float %r
+}
+
+; convertAtomicStoreToIntegerType
+define void @caststore(ptr %p, float %v) {
+; CHECK-LABEL: define void @caststore(
+; CHECK:    store atomic i32 {{%.*}}, ptr {{%.*}} seq_cst, align 4, !tbaa ![[TBAA]], !noalias ![[NOALIAS]]
+  store atomic float %v, ptr %p seq_cst, align 4, !tbaa !2, !noalias !6
+  ret void
+}
+
+; convertCmpXchgToIntegerType (pointer cmpxchg cast to integer)
+define { ptr, i1 } @castcmpxchg(ptr %p, ptr %c, ptr %n) {
+; CHECK-LABEL: define { ptr, i1 } @castcmpxchg(
+; CHECK:    cmpxchg ptr {{%.*}} seq_cst seq_cst, align 8, !tbaa ![[TBAA]], !noalias ![[NOALIAS]]
+  %r = cmpxchg ptr %p, ptr %c, ptr %n seq_cst seq_cst, align 8, !tbaa !2, !noalias !6
+  ret { ptr, i1 } %r
+}
+
+; expandAtomicLoadToCmpXchg (wide i128 load -> dummy cmpxchg, needs cx16)
+define i128 @load_cmpxchg(ptr %p) {
+; CX16-LABEL: define i128 @load_cmpxchg(
+; CX16:    cmpxchg ptr {{%.*}}, i128 0, i128 0 seq_cst seq_cst, align 16, !tbaa ![[TBAA]], !noalias ![[NOALIAS]]
+  %r = load atomic i128, ptr %p seq_cst, align 16, !tbaa !2, !noalias !6
+  ret i128 %r
+}
+
+!0 = !{!"alias-domain"}
+!1 = !{!"alias-scope-a", !0}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"int", !4, i64 0}
+!4 = !{!"omnipotent char", !5, i64 0}
+!5 = !{!"Simple C/C++ TBAA"}
+!6 = !{!1}

>From fbf43ea0b3569e32dd717818056627e8179f80c0 Mon Sep 17 00:00:00 2001
From: Ayush Rai <your-email at amd.com>
Date: Mon, 29 Jun 2026 12:47:57 +0530
Subject: [PATCH 3/3] [AtomicExpand] Preserve AA metadata on the seed load in
 insertRMWCmpXchgLoop

---
 llvm/lib/CodeGen/AtomicExpandPass.cpp         |  2 ++
 ...tomicrmw-cmpxchg-loop-preserve-metadata.ll | 22 +++++++++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 llvm/test/Transforms/AtomicExpand/X86/atomicrmw-cmpxchg-loop-preserve-metadata.ll

diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index 5ebbe1172f439..0a7033a0d15e9 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -1806,6 +1806,8 @@ Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
   // addIncoming is done first so that any replaceAllUsesWith calls during
   // normalization correctly update the PHI incoming value.
   InitLoaded->setVolatile(IsVolatile);
+  if (MetadataSrc)
+    copyMetadataForAtomic(*InitLoaded, *MetadataSrc);
   if (TLI->shouldIssueAtomicLoadForAtomicEmulationLoop()) {
     InitLoaded->setAtomic(AtomicOrdering::Monotonic, SSID);
     // The newly created load might need to be lowered further. Because it is
diff --git a/llvm/test/Transforms/AtomicExpand/X86/atomicrmw-cmpxchg-loop-preserve-metadata.ll b/llvm/test/Transforms/AtomicExpand/X86/atomicrmw-cmpxchg-loop-preserve-metadata.ll
new file mode 100644
index 0000000000000..54aa87e6c42df
--- /dev/null
+++ b/llvm/test/Transforms/AtomicExpand/X86/atomicrmw-cmpxchg-loop-preserve-metadata.ll
@@ -0,0 +1,22 @@
+; RUN: opt -S %s -passes='require<libcall-lowering-info>,atomic-expand' -mtriple=x86_64-linux-gnu | FileCheck %s
+
+; An atomicrmw that has no native instruction (e.g. nand) is expanded to a
+; cmpxchg retry loop by insertRMWCmpXchgLoop. The pre-loop seed load
+; (InitLoaded) must preserve the original !tbaa/!noalias metadata, matching the
+; widened cmpxchg in the loop.
+
+define i32 @atomicrmw_nand_preserves_metadata(ptr %p, i32 %v) {
+; CHECK-LABEL: define i32 @atomicrmw_nand_preserves_metadata(
+; CHECK:    load i32, ptr {{%.*}}, align 4, !tbaa ![[TBAA:[0-9]+]], !noalias ![[NOALIAS:[0-9]+]]
+; CHECK:    cmpxchg ptr {{%.*}} seq_cst seq_cst, align 4, !tbaa ![[TBAA]], !noalias ![[NOALIAS]]
+  %r = atomicrmw nand ptr %p, i32 %v seq_cst, align 4, !tbaa !2, !noalias !6
+  ret i32 %r
+}
+
+!0 = !{!"alias-domain"}
+!1 = !{!"alias-scope-a", !0}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"int", !4, i64 0}
+!4 = !{!"omnipotent char", !5, i64 0}
+!5 = !{!"Simple C/C++ TBAA"}
+!6 = !{!1}



More information about the llvm-commits mailing list