Author: Sirui Mu
Date: 2025-08-27T22:45:38+08:00
New Revision: a2bc0ca233574895091675518943f19aed1133ee

URL: 
https://github.com/llvm/llvm-project/commit/a2bc0ca233574895091675518943f19aed1133ee
DIFF: 
https://github.com/llvm/llvm-project/commit/a2bc0ca233574895091675518943f19aed1133ee.diff

LOG: [CIR] More atomic load and store (#155168)

This patch adds support for `__atomic_load_n` and `__atomic_store_n`
that were missed by #153814.

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
    clang/test/CIR/CodeGen/atomic.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 80aacb946e7c7..d8981c8c7ca56 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -265,6 +265,7 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr 
*expr, Address dest,
     llvm_unreachable("already handled!");
 
   case AtomicExpr::AO__c11_atomic_load:
+  case AtomicExpr::AO__atomic_load_n:
   case AtomicExpr::AO__atomic_load: {
     cir::LoadOp load =
         builder.createLoad(loc, ptr, /*isVolatile=*/expr->isVolatile());
@@ -278,6 +279,7 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr 
*expr, Address dest,
   }
 
   case AtomicExpr::AO__c11_atomic_store:
+  case AtomicExpr::AO__atomic_store_n:
   case AtomicExpr::AO__atomic_store: {
     cir::LoadOp loadVal1 = builder.createLoad(loc, val1);
 
@@ -305,13 +307,11 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr 
*expr, Address dest,
 
   case AtomicExpr::AO__opencl_atomic_load:
   case AtomicExpr::AO__hip_atomic_load:
-  case AtomicExpr::AO__atomic_load_n:
   case AtomicExpr::AO__scoped_atomic_load_n:
   case AtomicExpr::AO__scoped_atomic_load:
 
   case AtomicExpr::AO__opencl_atomic_store:
   case AtomicExpr::AO__hip_atomic_store:
-  case AtomicExpr::AO__atomic_store_n:
   case AtomicExpr::AO__scoped_atomic_store:
   case AtomicExpr::AO__scoped_atomic_store_n:
 
@@ -450,6 +450,7 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
   case AtomicExpr::AO__c11_atomic_init:
     llvm_unreachable("already handled above with emitAtomicInit");
 
+  case AtomicExpr::AO__atomic_load_n:
   case AtomicExpr::AO__c11_atomic_load:
     break;
 
@@ -461,6 +462,7 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
     val1 = emitPointerWithAlignment(e->getVal1());
     break;
 
+  case AtomicExpr::AO__atomic_store_n:
   case AtomicExpr::AO__c11_atomic_store:
     val1 = emitValToTemp(*this, e->getVal1());
     break;
@@ -507,9 +509,20 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
   }
 
   bool isStore = e->getOp() == AtomicExpr::AO__c11_atomic_store ||
-                 e->getOp() == AtomicExpr::AO__atomic_store;
+                 e->getOp() == AtomicExpr::AO__opencl_atomic_store ||
+                 e->getOp() == AtomicExpr::AO__hip_atomic_store ||
+                 e->getOp() == AtomicExpr::AO__atomic_store ||
+                 e->getOp() == AtomicExpr::AO__atomic_store_n ||
+                 e->getOp() == AtomicExpr::AO__scoped_atomic_store ||
+                 e->getOp() == AtomicExpr::AO__scoped_atomic_store_n ||
+                 e->getOp() == AtomicExpr::AO__atomic_clear;
   bool isLoad = e->getOp() == AtomicExpr::AO__c11_atomic_load ||
-                e->getOp() == AtomicExpr::AO__atomic_load;
+                e->getOp() == AtomicExpr::AO__opencl_atomic_load ||
+                e->getOp() == AtomicExpr::AO__hip_atomic_load ||
+                e->getOp() == AtomicExpr::AO__atomic_load ||
+                e->getOp() == AtomicExpr::AO__atomic_load_n ||
+                e->getOp() == AtomicExpr::AO__scoped_atomic_load ||
+                e->getOp() == AtomicExpr::AO__scoped_atomic_load_n;
 
   if (!order) {
     // We have evaluated the memory order as an integer constant in orderConst.

diff  --git a/clang/test/CIR/CodeGen/atomic.c b/clang/test/CIR/CodeGen/atomic.c
index 6c37fb7cd432d..8b947f795d1d4 100644
--- a/clang/test/CIR/CodeGen/atomic.c
+++ b/clang/test/CIR/CodeGen/atomic.c
@@ -75,6 +75,35 @@ void load(int *ptr) {
 // OGCG:   %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4
 // OGCG: }
 
+void load_n(int *ptr) {
+  int a;
+  a = __atomic_load_n(ptr, __ATOMIC_RELAXED);
+  a = __atomic_load_n(ptr, __ATOMIC_CONSUME);
+  a = __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
+  a = __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
+}
+
+// CIR-LABEL: @load_n
+// CIR:   %{{.+}} = cir.load align(4) atomic(relaxed) %{{.+}} : 
!cir.ptr<!s32i>, !s32i
+// CIR:   %{{.+}} = cir.load align(4) atomic(consume) %{{.+}} : 
!cir.ptr<!s32i>, !s32i
+// CIR:   %{{.+}} = cir.load align(4) atomic(acquire) %{{.+}} : 
!cir.ptr<!s32i>, !s32i
+// CIR:   %{{.+}} = cir.load align(4) atomic(seq_cst) %{{.+}} : 
!cir.ptr<!s32i>, !s32i
+// CIR: }
+
+// LLVM-LABEL: @load_n
+// LLVM:   %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4
+// LLVM:   %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4
+// LLVM:   %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4
+// LLVM:   %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4
+// LLVM: }
+
+// OGCG-LABEL: @load_n
+// OGCG:   %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4
+// OGCG:   %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4
+// OGCG:   %{{.+}} = load atomic i32, ptr %{{.+}} acquire, align 4
+// OGCG:   %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4
+// OGCG: }
+
 void c11_load(_Atomic(int) *ptr) {
   __c11_atomic_load(ptr, __ATOMIC_RELAXED);
   __c11_atomic_load(ptr, __ATOMIC_CONSUME);
@@ -127,6 +156,30 @@ void store(int *ptr, int x) {
 // OGCG:   store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4
 // OGCG: }
 
+void store_n(int *ptr, int x) {
+  __atomic_store_n(ptr, x, __ATOMIC_RELAXED);
+  __atomic_store_n(ptr, x, __ATOMIC_RELEASE);
+  __atomic_store_n(ptr, x, __ATOMIC_SEQ_CST);
+}
+
+// CIR-LABEL: @store_n
+// CIR:   cir.store align(4) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, 
!cir.ptr<!s32i>
+// CIR:   cir.store align(4) atomic(release) %{{.+}}, %{{.+}} : !s32i, 
!cir.ptr<!s32i>
+// CIR:   cir.store align(4) atomic(seq_cst) %{{.+}}, %{{.+}} : !s32i, 
!cir.ptr<!s32i>
+// CIR: }
+
+// LLVM-LABEL: @store_n
+// LLVM:   store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4
+// LLVM:   store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4
+// LLVM:   store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4
+// LLVM: }
+
+// OGCG-LABEL: @store_n
+// OGCG:   store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4
+// OGCG:   store atomic i32 %{{.+}}, ptr %{{.+}} release, align 4
+// OGCG:   store atomic i32 %{{.+}}, ptr %{{.+}} seq_cst, align 4
+// OGCG: }
+
 void c11_store(_Atomic(int) *ptr, int x) {
   __c11_atomic_store(ptr, x, __ATOMIC_RELAXED);
   __c11_atomic_store(ptr, x, __ATOMIC_RELEASE);


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to