[clang] [CIR] Add scoped atomic load operation (PR #171134)
@@ -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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
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)
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)
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/
