[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-09 Thread Andy Kaylor via cfe-commits


@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+void scoped_atomic_load(int *ptr) {
+  // CIR-LABEL: @scoped_atomic_load
+  // LLVM-LABEL: @scoped_atomic_load
+  // OGCG-LABEL: @scoped_atomic_load
+
+  int x;
+  __scoped_atomic_load(ptr, &x, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+  // CIR: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) 
%{{.+}} : !cir.ptr, !s32i
+  // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} syncscope("singlethread") 
monotonic, align 4

andykaylor wrote:

That's a fair point.

https://github.com/llvm/llvm-project/pull/171134
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-09 Thread Sirui Mu via cfe-commits


@@ -399,20 +399,14 @@ static void emitAtomicCmpXchgFailureSet(CIRGenFunction 
&cgf, AtomicExpr *e,
 static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
  Address ptr, Address val1, Address val2,
  Expr *isWeakExpr, Expr *failureOrderExpr, int64_t 
size,
- cir::MemOrder order) {
-  std::unique_ptr scopeModel = expr->getScopeModel();
-  if (scopeModel) {

Lancern wrote:

Updated. Aligned CIRGen code structure with the classic CG.

https://github.com/llvm/llvm-project/pull/171134
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-09 Thread Sirui Mu via cfe-commits

https://github.com/Lancern updated 
https://github.com/llvm/llvm-project/pull/171134

>From f0665b2be89a84459eb25f1ec686b32f6985bc60 Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 8 Dec 2025 22:20:50 +0800
Subject: [PATCH] [CIR] Add sync scope to atomic load operations

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |  5 +-
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 16 +++-
 clang/include/clang/CIR/MissingFeatures.h |  1 +
 clang/lib/CIR/CodeGen/CIRGenAtomic.cpp| 96 ++-
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  2 +
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  7 +-
 clang/test/CIR/CodeGen/atomic-scoped.c| 40 
 clang/test/CIR/CodeGen/atomic.c   | 34 +++
 8 files changed, 152 insertions(+), 49 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/atomic-scoped.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index aa47c4bce189b..b286e4b4ba1eb 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
-   alignmentAttr, cir::MemOrderAttr{});
+   alignmentAttr, cir::SyncScopeKindAttr{},
+   cir::MemOrderAttr{});
   }
 
   mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -366,7 +367,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
/*isVolatile=*/false, alignmentAttr,
-   /*mem_order=*/{});
+   /*sync_scope=*/{}, /*mem_order=*/{});
   }
 
   cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index fcc7585cf81a5..08043f597398b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -446,6 +446,15 @@ def CIR_MemOrder : CIR_I32EnumAttr<
 I32EnumAttrCase<"SequentiallyConsistent", 5, "seq_cst">
 ]>;
 
+//===--===//
+// C/C++ sync scope definitions
+//===--===//
+
+def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
+  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
+  I32EnumAttrCase<"System", 1, "system">
+]>;
+
 
//===--===//
 // AllocaOp
 
//===--===//
@@ -586,6 +595,7 @@ def CIR_LoadOp : CIR_Op<"load", [
UnitAttr:$isDeref,
UnitAttr:$is_volatile,
OptionalAttr:$alignment,
+   OptionalAttr:$sync_scope,
OptionalAttr:$mem_order);
   let results = (outs CIR_AnyType:$result);
 
@@ -593,6 +603,7 @@ def CIR_LoadOp : CIR_Op<"load", [
 (`deref` $isDeref^)?
 (`volatile` $is_volatile^)?
 (`align` `(` $alignment^ `)`)?
+(`syncscope` `(` $sync_scope^ `)`)?
 (`atomic` `(` $mem_order^ `)`)?
 $addr `:` qualified(type($addr)) `,` type($result) attr-dict
   }];
@@ -5265,11 +5276,6 @@ def CIR_AtomicFetchKind : CIR_I32EnumAttr<
 I32EnumAttrCase<"Min", 7, "min">
 ]>;
 
-def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
-  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
-  I32EnumAttrCase<"System", 1, "system">
-]>;
-
 def CIR_AtomicFetchOp : CIR_Op<"atomic.fetch", [
   AllTypesMatch<["result", "val"]>,
   TypesMatchWith<"type of 'val' must match the pointee type of 'ptr'",
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 826a4b13f5c0c..3d230edbc6156 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -180,6 +180,7 @@ struct MissingFeatures {
   static bool atomicInfoGetAtomicAddress() { return false; }
   static bool atomicScope() { return false; }
   static bool atomicSyncScopeID() { return false; }
+  static bool atomicMapTargetSyncScope() { return false; }
   static bool atomicTypes() { return false; }
   static bool atomicUseLibCall() { return false; }
   static bool atomicMicrosoftVolatile() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/CIR/CodeGen/CIRGenAto

[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread Sirui Mu via cfe-commits


@@ -399,20 +399,14 @@ static void emitAtomicCmpXchgFailureSet(CIRGenFunction 
&cgf, AtomicExpr *e,
 static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
  Address ptr, Address val1, Address val2,
  Expr *isWeakExpr, Expr *failureOrderExpr, int64_t 
size,
- cir::MemOrder order) {
-  std::unique_ptr scopeModel = expr->getScopeModel();
-  if (scopeModel) {

Lancern wrote:

> The divergence I was talking about is introduced by this PR. That is, 
> handling the scope model in emitAtomicExpr as opposed to handling it here.

I'll address this in the next revision of this PR.

https://github.com/llvm/llvm-project/pull/171134
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread Andy Kaylor via cfe-commits


@@ -399,20 +399,14 @@ static void emitAtomicCmpXchgFailureSet(CIRGenFunction 
&cgf, AtomicExpr *e,
 static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
  Address ptr, Address val1, Address val2,
  Expr *isWeakExpr, Expr *failureOrderExpr, int64_t 
size,
- cir::MemOrder order) {
-  std::unique_ptr scopeModel = expr->getScopeModel();
-  if (scopeModel) {

andykaylor wrote:

This divergence from the structure of classic codegen worries me. It looks like 
we need for the handling to be done here to cover the non-constant scope value 
case properly.

https://github.com/llvm/llvm-project/pull/171134
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread Andy Kaylor via cfe-commits


@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+void scoped_atomic_load(int *ptr) {
+  // CIR-LABEL: @scoped_atomic_load
+  // LLVM-LABEL: @scoped_atomic_load
+  // OGCG-LABEL: @scoped_atomic_load
+
+  int x;
+  __scoped_atomic_load(ptr, &x, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+  // CIR: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) 
%{{.+}} : !cir.ptr, !s32i
+  // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} syncscope("singlethread") 
monotonic, align 4

andykaylor wrote:

Why do we have this difference from OGCG?

https://github.com/llvm/llvm-project/pull/171134
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread Andy Kaylor via cfe-commits


@@ -749,6 +743,21 @@ static void emitAtomicExprWithDynamicMemOrder(
   });
 }
 
+// Map clang sync scope to CIR sync scope.
+static cir::SyncScopeKind convertSyncScopeToCIR(clang::SyncScope scope) {
+  switch (scope) {
+  default: {
+assert(!cir::MissingFeatures::atomicSyncScopeID());

andykaylor wrote:

This seems like it should have an `errorNYI` diagnostic. There are a lot of 
cases covered by this default.

https://github.com/llvm/llvm-project/pull/171134
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread Sirui Mu via cfe-commits

https://github.com/Lancern updated 
https://github.com/llvm/llvm-project/pull/171134

>From 09e659fdf70ea22356028c9b2a8ab8d0572283b0 Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 8 Dec 2025 22:20:50 +0800
Subject: [PATCH] [CIR] Add sync scope to atomic load operations

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |  5 +-
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 16 ++--
 clang/include/clang/CIR/MissingFeatures.h |  1 +
 clang/lib/CIR/CodeGen/CIRGenAtomic.cpp| 77 ++-
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  2 +
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  7 +-
 clang/test/CIR/CodeGen/atomic-scoped.c| 40 ++
 clang/test/CIR/CodeGen/atomic.c   | 30 
 8 files changed, 133 insertions(+), 45 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/atomic-scoped.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index aa47c4bce189b..b286e4b4ba1eb 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
-   alignmentAttr, cir::MemOrderAttr{});
+   alignmentAttr, cir::SyncScopeKindAttr{},
+   cir::MemOrderAttr{});
   }
 
   mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -366,7 +367,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
/*isVolatile=*/false, alignmentAttr,
-   /*mem_order=*/{});
+   /*sync_scope=*/{}, /*mem_order=*/{});
   }
 
   cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index fcc7585cf81a5..08043f597398b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -446,6 +446,15 @@ def CIR_MemOrder : CIR_I32EnumAttr<
 I32EnumAttrCase<"SequentiallyConsistent", 5, "seq_cst">
 ]>;
 
+//===--===//
+// C/C++ sync scope definitions
+//===--===//
+
+def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
+  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
+  I32EnumAttrCase<"System", 1, "system">
+]>;
+
 
//===--===//
 // AllocaOp
 
//===--===//
@@ -586,6 +595,7 @@ def CIR_LoadOp : CIR_Op<"load", [
UnitAttr:$isDeref,
UnitAttr:$is_volatile,
OptionalAttr:$alignment,
+   OptionalAttr:$sync_scope,
OptionalAttr:$mem_order);
   let results = (outs CIR_AnyType:$result);
 
@@ -593,6 +603,7 @@ def CIR_LoadOp : CIR_Op<"load", [
 (`deref` $isDeref^)?
 (`volatile` $is_volatile^)?
 (`align` `(` $alignment^ `)`)?
+(`syncscope` `(` $sync_scope^ `)`)?
 (`atomic` `(` $mem_order^ `)`)?
 $addr `:` qualified(type($addr)) `,` type($result) attr-dict
   }];
@@ -5265,11 +5276,6 @@ def CIR_AtomicFetchKind : CIR_I32EnumAttr<
 I32EnumAttrCase<"Min", 7, "min">
 ]>;
 
-def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
-  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
-  I32EnumAttrCase<"System", 1, "system">
-]>;
-
 def CIR_AtomicFetchOp : CIR_Op<"atomic.fetch", [
   AllTypesMatch<["result", "val"]>,
   TypesMatchWith<"type of 'val' must match the pointee type of 'ptr'",
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 826a4b13f5c0c..3d230edbc6156 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -180,6 +180,7 @@ struct MissingFeatures {
   static bool atomicInfoGetAtomicAddress() { return false; }
   static bool atomicScope() { return false; }
   static bool atomicSyncScopeID() { return false; }
+  static bool atomicMapTargetSyncScope() { return false; }
   static bool atomicTypes() { return false; }
   static bool atomicUseLibCall() { return false; }
   static bool atomicMicrosoftVolatile() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/CIR/CodeGen/CIRGen

[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread via cfe-commits

github-actions[bot] wrote:


# :penguin: Linux x64 Test Results

* 85775 tests passed
* 754 tests skipped
* 2 tests failed

## Failed Tests
(click on a test name to see its output)

### Clang

Clang.CIR/CodeGen/atomic.c

```
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 
-internal-isystem 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/22/include
 -nostdsysteminc -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir 
-emit-cir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c
 -o 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir
# executed command: 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 
-internal-isystem 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/22/include
 -nostdsysteminc -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir 
-emit-cir 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c
 -o 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir
# note: command had no output on stdout or stderr
# RUN: at line 2
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck 
--input-file=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c
 -check-prefix=CIR
# executed command: 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck 
--input-file=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir
 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c
 -check-prefix=CIR
# .---command stderr
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c:84:9:
 error: CIR: expected string not found in input
# | // CIR: %{{.+}} = cir.load align(4) atomic(relaxed) %{{.+}} : 
!cir.ptr, !s32i
# | ^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir:352:36:
 note: scanning from here
# |  cir.func no_inline dso_local @load(%arg0: !cir.ptr 
loc(fused[#loc27, #loc28])) {
# |^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir:357:12:
 note: possible intended match here
# |  %3 = cir.load align(4) syncscope(system) atomic(relaxed) %2 : 
!cir.ptr, !s32i loc(#loc824)
# |^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c:113:9:
 error: CIR: expected string not found in input
# | // CIR: %{{.+}} = cir.load align(4) atomic(relaxed) %{{.+}} : 
!cir.ptr, !s32i
# | ^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir:370:38:
 note: scanning from here
# |  cir.func no_inline dso_local @load_n(%arg0: !cir.ptr 
loc(fused[#loc46, #loc47])) {
# |  ^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir:379:12:
 note: possible intended match here
# |  %7 = cir.load align(4) syncscope(system) atomic(relaxed) %6 : 
!cir.ptr, !s32i loc(#loc831)
# |^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c:141:9:
 error: CIR: expected string not found in input
# | // CIR: %{{.+}} = cir.load align(4) atomic(relaxed) %{{.+}} : 
!cir.ptr, !s32i
# | ^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir:400:40:
 note: scanning from here
# |  cir.func no_inline dso_local @c11_load(%arg0: !cir.ptr 
loc(fused[#loc69, #loc70])) {
# |^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir:408:12:
 note: possible intended match here
# |  %6 = cir.load align(4) syncscope(system) atomic(relaxed) %5 : 
!cir.ptr, !s32i loc(#loc841)
# |^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/CIR/CodeGen/atomic.c:1148:15:
 error: CIR-NEXT: expected string not found in input
# |  // CIR-NEXT: %[[RES:.+]] = cir.load align(4) atomic(relaxed) %[[PTR]] : 
!cir.ptr, !s32i
# |   ^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/test/CIR/CodeGen/Output/atomic.c.tmp.cir:1455:25:
 note: scanning from here
# |  cir.case(default, []) {
# | ^
# | 
/home/gha/actions-runner/_work/llvm-project/llvm-

[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Sirui Mu (Lancern)


Changes

This patch upstreams scoped variant of atomic load operations from incubator.

---
Full diff: https://github.com/llvm/llvm-project/pull/171134.diff


7 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+3-2) 
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+11-5) 
- (modified) clang/include/clang/CIR/MissingFeatures.h (+1) 
- (modified) clang/lib/CIR/CodeGen/CIRGenAtomic.cpp (+56-21) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+2) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+5-2) 
- (added) clang/test/CIR/CodeGen/atomic-scoped.c (+40) 


``diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index aa47c4bce189b..b286e4b4ba1eb 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
-   alignmentAttr, cir::MemOrderAttr{});
+   alignmentAttr, cir::SyncScopeKindAttr{},
+   cir::MemOrderAttr{});
   }
 
   mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -366,7 +367,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
/*isVolatile=*/false, alignmentAttr,
-   /*mem_order=*/{});
+   /*sync_scope=*/{}, /*mem_order=*/{});
   }
 
   cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index fcc7585cf81a5..08043f597398b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -446,6 +446,15 @@ def CIR_MemOrder : CIR_I32EnumAttr<
 I32EnumAttrCase<"SequentiallyConsistent", 5, "seq_cst">
 ]>;
 
+//===--===//
+// C/C++ sync scope definitions
+//===--===//
+
+def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
+  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
+  I32EnumAttrCase<"System", 1, "system">
+]>;
+
 
//===--===//
 // AllocaOp
 
//===--===//
@@ -586,6 +595,7 @@ def CIR_LoadOp : CIR_Op<"load", [
UnitAttr:$isDeref,
UnitAttr:$is_volatile,
OptionalAttr:$alignment,
+   OptionalAttr:$sync_scope,
OptionalAttr:$mem_order);
   let results = (outs CIR_AnyType:$result);
 
@@ -593,6 +603,7 @@ def CIR_LoadOp : CIR_Op<"load", [
 (`deref` $isDeref^)?
 (`volatile` $is_volatile^)?
 (`align` `(` $alignment^ `)`)?
+(`syncscope` `(` $sync_scope^ `)`)?
 (`atomic` `(` $mem_order^ `)`)?
 $addr `:` qualified(type($addr)) `,` type($result) attr-dict
   }];
@@ -5265,11 +5276,6 @@ def CIR_AtomicFetchKind : CIR_I32EnumAttr<
 I32EnumAttrCase<"Min", 7, "min">
 ]>;
 
-def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
-  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
-  I32EnumAttrCase<"System", 1, "system">
-]>;
-
 def CIR_AtomicFetchOp : CIR_Op<"atomic.fetch", [
   AllTypesMatch<["result", "val"]>,
   TypesMatchWith<"type of 'val' must match the pointee type of 'ptr'",
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 826a4b13f5c0c..3d230edbc6156 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -180,6 +180,7 @@ struct MissingFeatures {
   static bool atomicInfoGetAtomicAddress() { return false; }
   static bool atomicScope() { return false; }
   static bool atomicSyncScopeID() { return false; }
+  static bool atomicMapTargetSyncScope() { return false; }
   static bool atomicTypes() { return false; }
   static bool atomicUseLibCall() { return false; }
   static bool atomicMicrosoftVolatile() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 4c94db5ddd457..78792b53a0b2f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.

[clang] [CIR] Add scoped atomic load operation (PR #171134)

2025-12-08 Thread Sirui Mu via cfe-commits

https://github.com/Lancern created 
https://github.com/llvm/llvm-project/pull/171134

This patch upstreams scoped variant of atomic load operations from incubator.

>From cf48ffb396fbcbd561fb353d1758735a1871e442 Mon Sep 17 00:00:00 2001
From: Sirui Mu 
Date: Mon, 8 Dec 2025 22:20:50 +0800
Subject: [PATCH] [CIR] Add sync scope to atomic load operations

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |  5 +-
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 16 ++--
 clang/include/clang/CIR/MissingFeatures.h |  1 +
 clang/lib/CIR/CodeGen/CIRGenAtomic.cpp| 77 ++-
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  2 +
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  7 +-
 clang/test/CIR/CodeGen/atomic-scoped.c| 40 ++
 7 files changed, 118 insertions(+), 30 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/atomic-scoped.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index aa47c4bce189b..b286e4b4ba1eb 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -205,7 +205,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr alignmentAttr = getAlignmentAttr(alignment);
 return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false, isVolatile,
-   alignmentAttr, cir::MemOrderAttr{});
+   alignmentAttr, cir::SyncScopeKindAttr{},
+   cir::MemOrderAttr{});
   }
 
   mlir::Value createAlignedLoad(mlir::Location loc, mlir::Value ptr,
@@ -366,7 +367,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 auto addr = createAlloca(loc, getPointerTo(type), type, {}, alignmentAttr);
 return cir::LoadOp::create(*this, loc, addr, /*isDeref=*/false,
/*isVolatile=*/false, alignmentAttr,
-   /*mem_order=*/{});
+   /*sync_scope=*/{}, /*mem_order=*/{});
   }
 
   cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index fcc7585cf81a5..08043f597398b 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -446,6 +446,15 @@ def CIR_MemOrder : CIR_I32EnumAttr<
 I32EnumAttrCase<"SequentiallyConsistent", 5, "seq_cst">
 ]>;
 
+//===--===//
+// C/C++ sync scope definitions
+//===--===//
+
+def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
+  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
+  I32EnumAttrCase<"System", 1, "system">
+]>;
+
 
//===--===//
 // AllocaOp
 
//===--===//
@@ -586,6 +595,7 @@ def CIR_LoadOp : CIR_Op<"load", [
UnitAttr:$isDeref,
UnitAttr:$is_volatile,
OptionalAttr:$alignment,
+   OptionalAttr:$sync_scope,
OptionalAttr:$mem_order);
   let results = (outs CIR_AnyType:$result);
 
@@ -593,6 +603,7 @@ def CIR_LoadOp : CIR_Op<"load", [
 (`deref` $isDeref^)?
 (`volatile` $is_volatile^)?
 (`align` `(` $alignment^ `)`)?
+(`syncscope` `(` $sync_scope^ `)`)?
 (`atomic` `(` $mem_order^ `)`)?
 $addr `:` qualified(type($addr)) `,` type($result) attr-dict
   }];
@@ -5265,11 +5276,6 @@ def CIR_AtomicFetchKind : CIR_I32EnumAttr<
 I32EnumAttrCase<"Min", 7, "min">
 ]>;
 
-def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [
-  I32EnumAttrCase<"SingleThread", 0, "single_thread">,
-  I32EnumAttrCase<"System", 1, "system">
-]>;
-
 def CIR_AtomicFetchOp : CIR_Op<"atomic.fetch", [
   AllTypesMatch<["result", "val"]>,
   TypesMatchWith<"type of 'val' must match the pointee type of 'ptr'",
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 826a4b13f5c0c..3d230edbc6156 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -180,6 +180,7 @@ struct MissingFeatures {
   static bool atomicInfoGetAtomicAddress() { return false; }
   static bool atomicScope() { return false; }
   static bool atomicSyncScopeID() { return false; }
+  static bool atomicMapTargetSyncScope() { return false; }
   static bool atomicTypes() { return false; }
   static bool atomicUseLibCall() { return false; }
   static bool atomicMicrosoftVolatile() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/