https://github.com/steffenlarsen created 
https://github.com/llvm/llvm-project/pull/220874

This commit fixes the preservation of volatile semantics for atomic RMW 
operations in CIR CodeGen.

>From 316c08a6875f784518ae3afa52450d8e0ff75deb Mon Sep 17 00:00:00 2001
From: Steffen Holst Larsen <[email protected]>
Date: Thu, 3 Sep 2026 06:03:08 -0500
Subject: [PATCH] [CIR] Preserve volatile semantics for atomic operations

This commit fixes the preservation of volatile semantics for atomic RMW
operations in CIR CodeGen.

Signed-off-by: Steffen Holst Larsen <[email protected]>
---
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  4 +--
 clang/test/CIR/CodeGen/atomic-scoped.c        | 13 +++++++++
 clang/test/CIR/CodeGen/atomic.c               | 28 +++++++++++++++++++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 233e6aaa15adb..1cea870626de1 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1230,7 +1230,7 @@ mlir::LogicalResult 
CIRToLLVMAtomicXchgOpLowering::matchAndRewrite(
   llvm::StringRef llvmSyncScope = getLLVMSyncScope(adaptor.getSyncScope());
   rewriter.replaceOpWithNewOp<mlir::LLVM::AtomicRMWOp>(
       op, mlir::LLVM::AtomicBinOp::xchg, adaptor.getPtr(), adaptor.getVal(),
-      llvmOrder, llvmSyncScope);
+      llvmOrder, llvmSyncScope, /*alignment=*/0, op.getIsVolatile());
   return mlir::success();
 }
 
@@ -1428,7 +1428,7 @@ mlir::LogicalResult 
CIRToLLVMAtomicFetchOpLowering::matchAndRewrite(
       getLLVMAtomicBinOp(op.getBinop(), isInt, isSignedInt);
   auto rmwVal = mlir::LLVM::AtomicRMWOp::create(
       rewriter, op.getLoc(), llvmBinOp, adaptor.getPtr(), adaptor.getVal(),
-      llvmOrder, llvmSyncScope);
+      llvmOrder, llvmSyncScope, /*alignment=*/0, op.getIsVolatile());
 
   mlir::Value result = rmwVal.getResult();
   if (!op.getFetchFirst()) {
diff --git a/clang/test/CIR/CodeGen/atomic-scoped.c 
b/clang/test/CIR/CodeGen/atomic-scoped.c
index 991f19bcbbd7c..aa7571d83cdc5 100644
--- a/clang/test/CIR/CodeGen/atomic-scoped.c
+++ b/clang/test/CIR/CodeGen/atomic-scoped.c
@@ -119,6 +119,19 @@ void scoped_atomic_exchange_n(int *ptr, int value) {
   // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4
 }
 
+void scoped_atomic_exchange_n_volatile(volatile int *ptr, int value) {
+  // CIR-BEFORE-TL-LABEL: @scoped_atomic_exchange_n_volatile
+  // CIR-LABEL: @scoped_atomic_exchange_n_volatile
+  // LLVM-LABEL: @scoped_atomic_exchange_n_volatile
+  // OGCG-LABEL: @scoped_atomic_exchange_n_volatile
+
+  __scoped_atomic_exchange_n(ptr, value, __ATOMIC_RELAXED, 
__MEMORY_SCOPE_SYSTEM);
+  // CIR-BEFORE-TL: cir.atomic.xchg relaxed syncscope(system) volatile 
%{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // CIR: %{{.+}} = cir.atomic.xchg relaxed syncscope(system) volatile 
%{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+  // LLVM: %{{.+}} = atomicrmw volatile xchg ptr %{{.+}}, i32 %{{.+}} 
monotonic, align 4
+  // OGCG: %{{.+}} = atomicrmw volatile xchg ptr %{{.+}}, i32 %{{.+}} 
monotonic, align 4
+}
+
 void scoped_atomic_cmpxchg(int *ptr, int *expected, int *desired) {
   // CIR-BEFORE-TL-LABEL: @scoped_atomic_cmpxchg
   // CIR-LABEL: @scoped_atomic_cmpxchg
diff --git a/clang/test/CIR/CodeGen/atomic.c b/clang/test/CIR/CodeGen/atomic.c
index 96a84eeac4929..21b99331fb417 100644
--- a/clang/test/CIR/CodeGen/atomic.c
+++ b/clang/test/CIR/CodeGen/atomic.c
@@ -929,6 +929,19 @@ void atomic_exchange_n(int *ptr, int value) {
   // OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
 }
 
+int atomic_exchange_n_volatile(volatile int *ptr, int value) {
+  // CIR-LABEL: @atomic_exchange_n_volatile
+  // LLVM-LABEL: @atomic_exchange_n_volatile
+  // OGCG-LABEL: @atomic_exchange_n_volatile
+
+  return __atomic_exchange_n(ptr, value, __ATOMIC_SEQ_CST);
+  // CIR: %{{.+}} = cir.atomic.xchg seq_cst syncscope(system) volatile 
%{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+
+  // LLVM: %{{.+}} = atomicrmw volatile xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, 
align 4
+
+  // OGCG: %{{.+}} = atomicrmw volatile xchg ptr %{{.+}}, i32 %{{.+}} seq_cst, 
align 4
+}
+
 void test_and_set(void *p) {
   // CIR-LABEL: @test_and_set
   // LLVM-LABEL: @test_and_set
@@ -1057,6 +1070,21 @@ int atomic_fetch_add(int *ptr, int value) {
   // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4
 }
 
+int atomic_fetch_add_volatile(volatile int *ptr, int value) {
+  // CIR-LABEL: @atomic_fetch_add_volatile
+  // LLVM-LABEL: @atomic_fetch_add_volatile
+  // OGCG-LABEL: @atomic_fetch_add_volatile
+
+  return __atomic_fetch_add(ptr, value, __ATOMIC_SEQ_CST);
+  // CIR: %{{.+}} = cir.atomic.fetch add seq_cst syncscope(system) fetch_first 
%{{.+}}, %{{.+}} volatile : (!cir.ptr<!s32i>, !s32i) -> !s32i
+
+  // LLVM:      %[[RES:.+]] = atomicrmw volatile add ptr %{{.+}}, i32 %{{.+}} 
seq_cst, align 4
+  // LLVM-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4
+
+  // OGCG:      %[[RES:.+]] = atomicrmw volatile add ptr %{{.+}}, i32 %{{.+}} 
seq_cst, align 4
+  // OGCG-NEXT: store i32 %[[RES]], ptr %{{.+}}, align 4
+}
+
 int *atomic_fetch_add_ptr(int **ptr, __PTRDIFF_TYPE__ value) {
   // CIR-LABEL: @atomic_fetch_add_ptr
   // LLVM-LABEL: @atomic_fetch_add_ptr

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to