https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/220884
>From 66a23ce74921885af60f6ef9f93a62e4a25436bc Mon Sep 17 00:00:00 2001 From: Henrich Lauko <[email protected]> Date: Thu, 3 Sep 2026 12:44:31 +0000 Subject: [PATCH] [CIR] Migrate MemOrder and SyncScopeKind off IntegerAttr MemOrder and SyncScopeKind, the enums the atomic operations share, generated IntegerAttr subclasses with no dialect spelling of their own. Both now set genSpecializedAttr = 0 and gain CIR_EnumAttr wrappers, spelling `#cir.mem_order<seq_cst>` and `#cir.sync_scope<system>`, and the atomic operations wrap their arguments in `enum()` to keep the bare keyword. `enum()` works as an optional-group anchor, so the `syncscope` and `atomic` groups on cir.load and cir.store are unaffected. Operation syntax is unchanged. --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 68 +++++++++++--------- clang/test/CIR/IR/enum-attrs.cir | 28 ++++++++ 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 1a4afd3b53d8b..bf2c38ef67f0c 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -642,7 +642,11 @@ def CIR_MemOrder : CIR_I32EnumAttr< I32EnumAttrCase<"Release", 3, "release">, I32EnumAttrCase<"AcquireRelease", 4, "acq_rel">, I32EnumAttrCase<"SequentiallyConsistent", 5, "seq_cst"> -]>; +]> { + let genSpecializedAttr = 0; +} + +def CIR_MemOrderAttr : CIR_EnumAttr<CIR_MemOrder, "mem_order">; //===----------------------------------------------------------------------===// // C/C++ sync scope definitions @@ -669,7 +673,11 @@ def CIR_SyncScopeKind : CIR_I32EnumAttr<"SyncScopeKind", "sync scope kind", [ I32EnumAttrCase<"OpenCLDevice", 13, "opencl_device">, I32EnumAttrCase<"OpenCLAllSVMDevices", 14, "opencl_all_svm_devices">, I32EnumAttrCase<"OpenCLSubGroup", 15, "opencl_sub_group">, -]>; +]> { + let genSpecializedAttr = 0; +} + +def CIR_SyncScopeKindAttr : CIR_EnumAttr<CIR_SyncScopeKind, "sync_scope">; //===----------------------------------------------------------------------===// // AllocaOp @@ -810,8 +818,8 @@ def CIR_LoadOp : CIR_Op<"load", [ UnitAttr:$is_volatile, UnitAttr:$is_nontemporal, OptionalAttr<I64Attr>:$alignment, - OptionalAttr<CIR_SyncScopeKind>:$sync_scope, - OptionalAttr<CIR_MemOrder>:$mem_order, + OptionalAttr<CIR_SyncScopeKindAttr>:$sync_scope, + OptionalAttr<CIR_MemOrderAttr>:$mem_order, UnitAttr:$invariant); let results = (outs CIR_AnyType:$result); @@ -821,8 +829,8 @@ def CIR_LoadOp : CIR_Op<"load", [ (`nontemporal` $is_nontemporal^)? (`invariant` $invariant^)? (`align` `(` $alignment^ `)`)? - (`syncscope` `(` $sync_scope^ `)`)? - (`atomic` `(` $mem_order^ `)`)? + (`syncscope` `(` enum($sync_scope)^ `)`)? + (`atomic` `(` enum($mem_order)^ `)`)? $addr `:` qualified(type($addr)) `,` type($result) attr-dict }]; @@ -913,15 +921,15 @@ def CIR_StoreOp : CIR_Op<"store", [ UnitAttr:$is_volatile, UnitAttr:$is_nontemporal, OptionalAttr<I64Attr>:$alignment, - OptionalAttr<CIR_SyncScopeKind>:$sync_scope, - OptionalAttr<CIR_MemOrder>:$mem_order); + OptionalAttr<CIR_SyncScopeKindAttr>:$sync_scope, + OptionalAttr<CIR_MemOrderAttr>:$mem_order); let assemblyFormat = [{ (`volatile` $is_volatile^)? (`nontemporal` $is_nontemporal^)? (`align` `(` $alignment^ `)`)? - (`syncscope` `(` $sync_scope^ `)`)? - (`atomic` `(` $mem_order^ `)`)? + (`syncscope` `(` enum($sync_scope)^ `)`)? + (`atomic` `(` enum($mem_order)^ `)`)? $value `,` $addr attr-dict `:` type($value) `,` qualified(type($addr)) }]; @@ -8918,15 +8926,15 @@ def CIR_AtomicFetchOp : CIR_Op<"atomic.fetch", [ Arg<CIR_PtrToIntOrFloatType, "", [MemRead, MemWrite]>:$ptr, CIR_AnyIntOrFloatType:$val, CIR_AtomicFetchKind:$binop, - Arg<CIR_MemOrder, "memory order">:$mem_order, - Arg<CIR_SyncScopeKind, "synchronization scope">:$sync_scope, + Arg<CIR_MemOrderAttr, "memory order">:$mem_order, + Arg<CIR_SyncScopeKindAttr, "synchronization scope">:$sync_scope, UnitAttr:$is_volatile, UnitAttr:$fetch_first ); let assemblyFormat = [{ - $binop $mem_order - `syncscope` `(` $sync_scope `)` + $binop enum($mem_order) + `syncscope` `(` enum($sync_scope) `)` (`fetch_first` $fetch_first^)? $ptr `,` $val (`volatile` $is_volatile^)? @@ -8974,14 +8982,14 @@ def CIR_AtomicXchgOp : CIR_Op<"atomic.xchg", [ let arguments = (ins Arg<CIR_PointerType, "", [MemRead, MemWrite]>:$ptr, CIR_AnyType:$val, - Arg<CIR_MemOrder, "memory order">:$mem_order, - CIR_SyncScopeKind:$sync_scope, + Arg<CIR_MemOrderAttr, "memory order">:$mem_order, + CIR_SyncScopeKindAttr:$sync_scope, UnitAttr:$is_volatile ); let assemblyFormat = [{ - $mem_order - `syncscope` `(` $sync_scope `)` + enum($mem_order) + `syncscope` `(` enum($sync_scope) `)` (`volatile` $is_volatile^)? $ptr `,` $val `:` functional-type(operands, results) attr-dict @@ -9038,17 +9046,17 @@ def CIR_AtomicCmpXchgOp : CIR_Op<"atomic.cmpxchg", [ let arguments = (ins Arg<CIR_PointerType, "", [MemRead, MemWrite]>:$ptr, CIR_AnyType:$expected, CIR_AnyType:$desired, - Arg<CIR_MemOrder, "success memory order">:$succ_order, - Arg<CIR_MemOrder, "failure memory order">:$fail_order, - CIR_SyncScopeKind:$sync_scope, + Arg<CIR_MemOrderAttr, "success memory order">:$succ_order, + Arg<CIR_MemOrderAttr, "failure memory order">:$fail_order, + CIR_SyncScopeKindAttr:$sync_scope, OptionalAttr<I64Attr>:$alignment, UnitAttr:$weak, UnitAttr:$is_volatile); let assemblyFormat = [{ (`weak` $weak^)? - `success` `(` $succ_order `)` `failure` `(` $fail_order `)` - `syncscope` `(` $sync_scope `)` + `success` `(` enum($succ_order) `)` `failure` `(` enum($fail_order) `)` + `syncscope` `(` enum($sync_scope) `)` $ptr `,` $expected `,` $desired (`align` `(` $alignment^ `)`)? (`volatile` $is_volatile^)? @@ -9075,7 +9083,7 @@ def CIR_AtomicTestAndSetOp : CIR_Op<"atomic.test_and_set"> { let arguments = (ins Arg<CIR_PtrToType<CIR_SInt8>, "", [MemRead, MemWrite]>:$ptr, - Arg<CIR_MemOrder, "memory order">:$mem_order, + Arg<CIR_MemOrderAttr, "memory order">:$mem_order, OptionalAttr<I64Attr>:$alignment, UnitAttr:$is_volatile ); @@ -9083,7 +9091,7 @@ def CIR_AtomicTestAndSetOp : CIR_Op<"atomic.test_and_set"> { let results = (outs CIR_BoolType:$result); let assemblyFormat = [{ - $mem_order $ptr + enum($mem_order) $ptr (`volatile` $is_volatile^)? `:` qualified(type($ptr)) `->` qualified(type($result)) attr-dict }]; @@ -9106,13 +9114,13 @@ def CIR_AtomicClearOp : CIR_Op<"atomic.clear"> { let arguments = (ins Arg<CIR_PtrToType<CIR_SInt8>, "", [MemRead, MemWrite]>:$ptr, - Arg<CIR_MemOrder, "memory order">:$mem_order, + Arg<CIR_MemOrderAttr, "memory order">:$mem_order, OptionalAttr<I64Attr>:$alignment, UnitAttr:$is_volatile ); let assemblyFormat = [{ - $mem_order $ptr + enum($mem_order) $ptr (`volatile` $is_volatile^)? `:` qualified(type($ptr)) attr-dict }]; @@ -9139,12 +9147,12 @@ def CIR_AtomicFenceOp : CIR_Op<"atomic.fence"> { }]; let arguments = (ins - Arg<CIR_MemOrder, "memory order">:$ordering, - OptionalAttr<CIR_SyncScopeKind>:$syncscope + Arg<CIR_MemOrderAttr, "memory order">:$ordering, + OptionalAttr<CIR_SyncScopeKindAttr>:$syncscope ); let assemblyFormat = [{ - (`syncscope` `(` $syncscope^ `)`)? $ordering attr-dict + (`syncscope` `(` enum($syncscope)^ `)`)? enum($ordering) attr-dict }]; } diff --git a/clang/test/CIR/IR/enum-attrs.cir b/clang/test/CIR/IR/enum-attrs.cir index d8972ea918707..4bb5ac08c4717 100644 --- a/clang/test/CIR/IR/enum-attrs.cir +++ b/clang/test/CIR/IR/enum-attrs.cir @@ -5,6 +5,8 @@ // dictionary. These used to be IntegerAttr subclasses, which printed as // `2 : i32`. +!s32i = !cir.int<s, 32> + module { // CHECK-LABEL: cir.func @cast_attr() { @@ -62,4 +64,30 @@ cir.func @tls_model_attr() { #cir.tls_model<tls_local_exec>]} } +// CHECK-LABEL: cir.func @mem_order_attr() { +cir.func @mem_order_attr() { + // CHECK: cir.return {cir.test = [#cir.mem_order<relaxed>, #cir.mem_order<acq_rel>, #cir.mem_order<seq_cst>]} + cir.return {cir.test = [#cir.mem_order<relaxed>, #cir.mem_order<acq_rel>, + #cir.mem_order<seq_cst>]} +} + +// CHECK-LABEL: cir.func @sync_scope_attr() { +cir.func @sync_scope_attr() { + // CHECK: cir.return {cir.test = [#cir.sync_scope<single_thread>, #cir.sync_scope<hip_workgroup>, #cir.sync_scope<opencl_all_svm_devices>]} + cir.return {cir.test = [#cir.sync_scope<single_thread>, + #cir.sync_scope<hip_workgroup>, + #cir.sync_scope<opencl_all_svm_devices>]} +} + +// The operations themselves keep printing a bare keyword. + +// CHECK-LABEL: cir.func @mem_order_sync_scope_ops(%arg0: !cir.ptr<!s32i>) { +cir.func @mem_order_sync_scope_ops(%arg0: !cir.ptr<!s32i>) { + // CHECK: %0 = cir.load syncscope(system) atomic(seq_cst) %arg0 : !cir.ptr<!s32i>, !s32i + %0 = cir.load syncscope(system) atomic(seq_cst) %arg0 : !cir.ptr<!s32i>, !s32i + // CHECK: cir.atomic.fence syncscope(system) seq_cst + cir.atomic.fence syncscope(system) seq_cst + cir.return +} + } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
