[clang] [CIR] Add sync scope to atomic fetch-and-update operation (PR #180770)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 10 08:20:44 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Sirui Mu (Lancern)
<details>
<summary>Changes</summary>
This patch adds synchronization scope support to the `cir.atomic.fetch` operation.
Most of the test code is generated by an AI agent. The generated tests are manually reviewed and verified.
Assisted-by: Copilot with GPT-5.2-Codex
---
Patch is 76.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/180770.diff
7 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+2)
- (modified) clang/lib/CIR/CodeGen/CIRGenAtomic.cpp (+32-25)
- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp (+2-2)
- (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp (+1-1)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+4-3)
- (modified) clang/test/CIR/CodeGen/atomic-scoped.c (+304)
- (modified) clang/test/CIR/CodeGen/atomic.c (+82-82)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 906bd247f60ef..82804f2455112 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -6379,12 +6379,14 @@ def CIR_AtomicFetchOp : CIR_Op<"atomic.fetch", [
CIR_AnyIntOrFloatType:$val,
CIR_AtomicFetchKind:$binop,
Arg<CIR_MemOrder, "memory order">:$mem_order,
+ Arg<CIR_SyncScopeKind, "synchronization scope">:$sync_scope,
UnitAttr:$is_volatile,
UnitAttr:$fetch_first
);
let assemblyFormat = [{
$binop $mem_order
+ `syncscope` `(` $sync_scope `)`
(`fetch_first` $fetch_first^)?
$ptr `,` $val
(`volatile` $is_volatile^)?
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index a78b15511dd82..7f07070ab2342 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -476,80 +476,96 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
break;
case AtomicExpr::AO__atomic_add_fetch:
+ case AtomicExpr::AO__scoped_atomic_add_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_add:
case AtomicExpr::AO__atomic_fetch_add:
+ case AtomicExpr::AO__scoped_atomic_fetch_add:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::Add);
break;
case AtomicExpr::AO__atomic_sub_fetch:
+ case AtomicExpr::AO__scoped_atomic_sub_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_sub:
case AtomicExpr::AO__atomic_fetch_sub:
+ case AtomicExpr::AO__scoped_atomic_fetch_sub:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::Sub);
break;
case AtomicExpr::AO__atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_min:
case AtomicExpr::AO__atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_min:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::Min);
break;
case AtomicExpr::AO__atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_max:
case AtomicExpr::AO__atomic_fetch_max:
+ case AtomicExpr::AO__scoped_atomic_fetch_max:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::Max);
break;
case AtomicExpr::AO__atomic_and_fetch:
+ case AtomicExpr::AO__scoped_atomic_and_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_and:
case AtomicExpr::AO__atomic_fetch_and:
+ case AtomicExpr::AO__scoped_atomic_fetch_and:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::And);
break;
case AtomicExpr::AO__atomic_or_fetch:
+ case AtomicExpr::AO__scoped_atomic_or_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_or:
case AtomicExpr::AO__atomic_fetch_or:
+ case AtomicExpr::AO__scoped_atomic_fetch_or:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::Or);
break;
case AtomicExpr::AO__atomic_xor_fetch:
+ case AtomicExpr::AO__scoped_atomic_xor_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_xor:
case AtomicExpr::AO__atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_fetch_xor:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::Xor);
break;
case AtomicExpr::AO__atomic_nand_fetch:
+ case AtomicExpr::AO__scoped_atomic_nand_fetch:
fetchFirst = false;
[[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_nand:
case AtomicExpr::AO__atomic_fetch_nand:
+ case AtomicExpr::AO__scoped_atomic_fetch_nand:
opName = cir::AtomicFetchOp::getOperationName();
fetchAttr = cir::AtomicFetchKindAttr::get(builder.getContext(),
cir::AtomicFetchKind::Nand);
@@ -592,51 +608,26 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest,
case AtomicExpr::AO__hip_atomic_exchange:
case AtomicExpr::AO__opencl_atomic_exchange:
- case AtomicExpr::AO__scoped_atomic_add_fetch:
-
case AtomicExpr::AO__hip_atomic_fetch_add:
case AtomicExpr::AO__opencl_atomic_fetch_add:
- case AtomicExpr::AO__scoped_atomic_fetch_add:
-
- case AtomicExpr::AO__scoped_atomic_sub_fetch:
case AtomicExpr::AO__hip_atomic_fetch_sub:
case AtomicExpr::AO__opencl_atomic_fetch_sub:
- case AtomicExpr::AO__scoped_atomic_fetch_sub:
-
- case AtomicExpr::AO__scoped_atomic_min_fetch:
case AtomicExpr::AO__hip_atomic_fetch_min:
case AtomicExpr::AO__opencl_atomic_fetch_min:
- case AtomicExpr::AO__scoped_atomic_fetch_min:
-
- case AtomicExpr::AO__scoped_atomic_max_fetch:
case AtomicExpr::AO__hip_atomic_fetch_max:
case AtomicExpr::AO__opencl_atomic_fetch_max:
- case AtomicExpr::AO__scoped_atomic_fetch_max:
-
- case AtomicExpr::AO__scoped_atomic_and_fetch:
case AtomicExpr::AO__hip_atomic_fetch_and:
case AtomicExpr::AO__opencl_atomic_fetch_and:
- case AtomicExpr::AO__scoped_atomic_fetch_and:
-
- case AtomicExpr::AO__scoped_atomic_or_fetch:
case AtomicExpr::AO__hip_atomic_fetch_or:
case AtomicExpr::AO__opencl_atomic_fetch_or:
- case AtomicExpr::AO__scoped_atomic_fetch_or:
-
- case AtomicExpr::AO__scoped_atomic_xor_fetch:
case AtomicExpr::AO__hip_atomic_fetch_xor:
case AtomicExpr::AO__opencl_atomic_fetch_xor:
- case AtomicExpr::AO__scoped_atomic_fetch_xor:
-
- case AtomicExpr::AO__scoped_atomic_nand_fetch:
-
- case AtomicExpr::AO__scoped_atomic_fetch_nand:
case AtomicExpr::AO__scoped_atomic_fetch_uinc:
case AtomicExpr::AO__scoped_atomic_fetch_udec:
@@ -927,6 +918,14 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
case AtomicExpr::AO__atomic_sub_fetch:
case AtomicExpr::AO__c11_atomic_fetch_max:
case AtomicExpr::AO__c11_atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_add:
+ case AtomicExpr::AO__scoped_atomic_fetch_max:
+ case AtomicExpr::AO__scoped_atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_sub:
+ case AtomicExpr::AO__scoped_atomic_add_fetch:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_sub_fetch:
shouldCastToIntPtrTy = !memTy->isFloatingType();
[[fallthrough]];
@@ -946,6 +945,14 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
case AtomicExpr::AO__c11_atomic_fetch_xor:
case AtomicExpr::AO__c11_atomic_exchange:
case AtomicExpr::AO__c11_atomic_store:
+ case AtomicExpr::AO__scoped_atomic_fetch_and:
+ case AtomicExpr::AO__scoped_atomic_fetch_nand:
+ case AtomicExpr::AO__scoped_atomic_fetch_or:
+ case AtomicExpr::AO__scoped_atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_and_fetch:
+ case AtomicExpr::AO__scoped_atomic_nand_fetch:
+ case AtomicExpr::AO__scoped_atomic_or_fetch:
+ case AtomicExpr::AO__scoped_atomic_xor_fetch:
case AtomicExpr::AO__scoped_atomic_store_n:
case AtomicExpr::AO__scoped_atomic_exchange_n:
val1 = emitValToTemp(*this, e->getVal1());
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index 5e6c9e8e2490e..df3b4203d8007 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -156,8 +156,8 @@ static mlir::Value makeBinaryAtomicValue(
auto rmwi = cir::AtomicFetchOp::create(
builder, cgf.getLoc(expr->getSourceRange()), destValue, val, kind,
- ordering, false, /* is volatile */
- true); /* fetch first */
+ ordering, cir::SyncScopeKind::System, false, /* is volatile */
+ true); /* fetch first */
return rmwi->getResult(0);
}
diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp
index 656f29dab4e92..62258be9d9d5e 100644
--- a/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering.cpp
@@ -58,7 +58,7 @@ void TargetLoweringPass::runOnOperation() {
}
mod->walk([&](mlir::Operation *op) {
- if (mlir::isa<cir::LoadOp, cir::StoreOp>(op))
+ if (mlir::isa<cir::LoadOp, cir::StoreOp, cir::AtomicFetchOp>(op))
convertSyncScopeIfPresent(op, *lowerModule);
});
}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index d411f7fa925ea..96d408149d21c 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1027,11 +1027,12 @@ mlir::LogicalResult CIRToLLVMAtomicFetchOpLowering::matchAndRewrite(
}
mlir::LLVM::AtomicOrdering llvmOrder = getLLVMMemOrder(op.getMemOrder());
+ llvm::StringRef llvmSyncScope = getLLVMSyncScope(op.getSyncScope());
mlir::LLVM::AtomicBinOp llvmBinOp =
getLLVMAtomicBinOp(op.getBinop(), isInt, isSignedInt);
- auto rmwVal = mlir::LLVM::AtomicRMWOp::create(rewriter, op.getLoc(),
- llvmBinOp, adaptor.getPtr(),
- adaptor.getVal(), llvmOrder);
+ auto rmwVal = mlir::LLVM::AtomicRMWOp::create(
+ rewriter, op.getLoc(), llvmBinOp, adaptor.getPtr(), adaptor.getVal(),
+ llvmOrder, llvmSyncScope);
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 d34b95b9a305a..5881df55b329f 100644
--- a/clang/test/CIR/CodeGen/atomic-scoped.c
+++ b/clang/test/CIR/CodeGen/atomic-scoped.c
@@ -112,3 +112,307 @@ void scoped_atomic_exchange_n(int *ptr, int value) {
// LLVM: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4
// OGCG: %{{.+}} = atomicrmw xchg ptr %{{.+}}, i32 %{{.+}} monotonic, align 4
}
+
+void scoped_atomic_fetch_add(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_fetch_add
+ // CIR-LABEL: @scoped_atomic_fetch_add
+ // LLVM-LABEL: @scoped_atomic_fetch_add
+ // OGCG-LABEL: @scoped_atomic_fetch_add
+
+ __scoped_atomic_fetch_add(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch add seq_cst syncscope(single_thread) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_fetch_add(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch add seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch add seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_add_fetch(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_add_fetch
+ // CIR-LABEL: @scoped_atomic_add_fetch
+ // LLVM-LABEL: @scoped_atomic_add_fetch
+ // OGCG-LABEL: @scoped_atomic_add_fetch
+
+ __scoped_atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch add seq_cst syncscope(single_thread) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch add seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch add seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch add seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw add ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_fetch_sub(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_fetch_sub
+ // CIR-LABEL: @scoped_atomic_fetch_sub
+ // LLVM-LABEL: @scoped_atomic_fetch_sub
+ // OGCG-LABEL: @scoped_atomic_fetch_sub
+
+ __scoped_atomic_fetch_sub(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch sub seq_cst syncscope(single_thread) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_fetch_sub(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch sub seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_sub_fetch(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_sub_fetch
+ // CIR-LABEL: @scoped_atomic_sub_fetch
+ // LLVM-LABEL: @scoped_atomic_sub_fetch
+ // OGCG-LABEL: @scoped_atomic_sub_fetch
+
+ __scoped_atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch sub seq_cst syncscope(single_thread) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch sub seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch sub seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch sub seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw sub ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_fetch_min(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_fetch_min
+ // CIR-LABEL: @scoped_atomic_fetch_min
+ // LLVM-LABEL: @scoped_atomic_fetch_min
+ // OGCG-LABEL: @scoped_atomic_fetch_min
+
+ __scoped_atomic_fetch_min(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch min seq_cst syncscope(single_thread) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch min seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_fetch_min(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch min seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch min seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_min_fetch(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_min_fetch
+ // CIR-LABEL: @scoped_atomic_min_fetch
+ // LLVM-LABEL: @scoped_atomic_min_fetch
+ // OGCG-LABEL: @scoped_atomic_min_fetch
+
+ __scoped_atomic_min_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch min seq_cst syncscope(single_thread) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch min seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_min_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch min seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch min seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw min ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_fetch_max(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_fetch_max
+ // CIR-LABEL: @scoped_atomic_fetch_max
+ // LLVM-LABEL: @scoped_atomic_fetch_max
+ // OGCG-LABEL: @scoped_atomic_fetch_max
+
+ __scoped_atomic_fetch_max(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch max seq_cst syncscope(single_thread) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch max seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_fetch_max(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch max seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch max seq_cst syncscope(system) fetch_first %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_max_fetch(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_max_fetch
+ // CIR-LABEL: @scoped_atomic_max_fetch
+ // LLVM-LABEL: @scoped_atomic_max_fetch
+ // OGCG-LABEL: @scoped_atomic_max_fetch
+
+ __scoped_atomic_max_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SINGLE);
+ // CIR-BEFORE-TL: cir.atomic.fetch max seq_cst syncscope(single_thread) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch max seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+
+ __scoped_atomic_max_fetch(ptr, 1, __ATOMIC_SEQ_CST, __MEMORY_SCOPE_SYSTEM);
+ // CIR-BEFORE-TL: cir.atomic.fetch max seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // CIR: cir.atomic.fetch max seq_cst syncscope(system) %{{.+}}, %{{.+}} : (!cir.ptr<!s32i>, !s32i) -> !s32i
+ // LLVM: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+ // OGCG: atomicrmw max ptr %{{.+}}, i32 %{{.+}} seq_cst, align 4
+}
+
+void scoped_atomic_fetch_and(int *ptr, int *value) {
+ // CIR-BEFORE-TL-LABEL: @scoped_atomic_fetch_and
+ // CIR-LABEL: @scoped_atomic_fetch_and
+ // LLVM-LABEL: @scoped...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/180770
More information about the cfe-commits
mailing list