[llvm-branch-commits] [clang] [CIR] Migrate GlobalLinkageKind, CallingConv and SideEffect off IntegerAttr (PR #220887)

Henrich Lauko via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Sep 3 06:46:13 PDT 2026


https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/220887

>From d9cdc4163028a0a5b757b070620ac269a21ee1e1 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Thu, 3 Sep 2026 12:44:31 +0000
Subject: [PATCH] [CIR] Migrate GlobalLinkageKind, CallingConv and SideEffect
 off IntegerAttr

GlobalLinkageKind, CallingConv and SideEffect generated IntegerAttr
subclasses with no dialect spelling of their own. Each now sets
genSpecializedAttr = 0 and gains a CIR_EnumAttr wrapper, and cir.global wraps
$linkage in `enum()`. GlobalLinkageKind spells `#cir.linkage<internal>`,
dropping both the `global_` prefix and the `_kind` suffix.

cir.func and cir.call print all three by hand, but they stream
stringifyGlobalLinkageKind(getLinkage()) and friends, which take the enum
rather than the attribute, so those sites are unchanged.

Operation syntax is unchanged.
---
 .../include/clang/CIR/Dialect/IR/CIRAttrs.td  |  4 +++
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 25 ++++++++++-----
 clang/test/CIR/IR/enum-attrs.cir              | 31 +++++++++++++++++++
 3 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index f88ffa1ff7c0d..2052ddeb577d9 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -1840,8 +1840,12 @@ def CIR_SideEffect : CIR_I32EnumAttr<
     %2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(const)
     ```
   }];
+
+  let genSpecializedAttr = 0;
 }
 
+def CIR_SideEffectAttr : CIR_EnumAttr<CIR_SideEffect, "side_effect">;
+
 //===----------------------------------------------------------------------===//
 // StaticLocalGuardAttr
 //===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index b89ea1dc5950b..ad4e6600cddf1 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3333,7 +3333,12 @@ def CIR_GlobalLinkageKind : CIR_I32EnumAttr<
     I32EnumAttrCase<"ExternalWeakLinkage", 9, "extern_weak">,
     // Tentative definitions.
     I32EnumAttrCase<"CommonLinkage", 10, "common">
-]>;
+]> {
+  let genSpecializedAttr = 0;
+}
+
+def CIR_GlobalLinkageKindAttr
+    : CIR_EnumAttr<CIR_GlobalLinkageKind, "linkage">;
 
 // TODO(CIR): For starters, cir.global has only name and type.  The other
 // properties of a global variable will be added over time as more of ClangIR
@@ -3400,7 +3405,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
                        >:$global_visibility,
                        OptionalAttr<StrAttr>:$sym_visibility,
                        TypeAttr:$sym_type,
-                       CIR_GlobalLinkageKind:$linkage,
+                       CIR_GlobalLinkageKindAttr:$linkage,
                        OptionalAttr<MemorySpaceAttrInterface>:$addr_space,
                        OptionalAttr<CIR_TLSModelAttr>:$tls_model,
                        OptionalAttr<CIR_ThreadLocalGlobalWrapperInitAttr>:$tls_refs,
@@ -3426,7 +3431,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
     ($sym_visibility^)?
     ($global_visibility^)?
     (`constant` $constant^)?
-    $linkage
+    enum($linkage)
     (`comdat` $comdat^)?
     (`tls_model` `=` enum($tls_model)^)?
     (`tls_refs` `=` $tls_refs^)?
@@ -4191,7 +4196,11 @@ def CIR_CallingConv : CIR_I32EnumAttr<"CallingConv", "calling convention", [
   I32EnumAttrCase<"SpirFunction", 2, "spir_function">,
   I32EnumAttrCase<"SpirKernel", 3, "spir_kernel">,
   I32EnumAttrCase<"AMDGPUKernel", 4, "amdgpu_kernel">
-]>;
+]> {
+  let genSpecializedAttr = 0;
+}
+
+def CIR_CallingConvAttr : CIR_EnumAttr<CIR_CallingConv, "calling_conv">;
 
 def CIR_FuncOp : CIR_Op<"func", [
   AutomaticAllocationScope, CallableOpInterface, SymbolName, SymbolVisibility,
@@ -4285,11 +4294,11 @@ def CIR_FuncOp : CIR_Op<"func", [
     UnitAttr:$no_proto,
     UnitAttr:$dso_local,
     DefaultValuedAttr<
-      CIR_GlobalLinkageKind,
+      CIR_GlobalLinkageKindAttr,
       "cir::GlobalLinkageKind::ExternalLinkage"
     >:$linkage,
     DefaultValuedAttr<
-      CIR_CallingConv,
+      CIR_CallingConvAttr,
       "cir::CallingConv::C"
     >:$calling_conv,
     OptionalAttr<StrAttr>:$sym_visibility,
@@ -4297,7 +4306,7 @@ def CIR_FuncOp : CIR_Op<"func", [
     OptionalAttr<DictArrayAttr>:$arg_attrs,
     OptionalAttr<DictArrayAttr>:$res_attrs,
     OptionalAttr<FlatSymbolRefAttr>:$aliasee,
-    OptionalAttr<CIR_SideEffect>:$side_effect,
+    OptionalAttr<CIR_SideEffectAttr>:$side_effect,
     OptionalAttr<FlatSymbolRefAttr>:$personality,
     CIR_OptionalPriorityAttr:$global_ctor_priority,
     CIR_OptionalPriorityAttr:$global_dtor_priority,
@@ -4601,7 +4610,7 @@ class CIR_CallOpBase<string mnemonic, list<Trait> extra_traits = []>
       UnitAttr:$nothrow,
       OptionalAttr<CIR_InlineKindAttr>:$inline_kind,
       UnitAttr:$musttail,
-      DefaultValuedAttr<CIR_SideEffect, "SideEffect::All">:$side_effect,
+      DefaultValuedAttr<CIR_SideEffectAttr, "SideEffect::All">:$side_effect,
       OptionalAttr<DictArrayAttr>:$arg_attrs,
       OptionalAttr<DictArrayAttr>:$res_attrs
       );
diff --git a/clang/test/CIR/IR/enum-attrs.cir b/clang/test/CIR/IR/enum-attrs.cir
index ca020a8b28030..aafc58e792678 100644
--- a/clang/test/CIR/IR/enum-attrs.cir
+++ b/clang/test/CIR/IR/enum-attrs.cir
@@ -117,6 +117,31 @@ cir.func @asm_flavor_attr() {
 // CHECK: cir.func @asm_flavor_attr() {
 // CHECK:   cir.return {cir.test = [#cir.asm_flavor<x86_att>, #cir.asm_flavor<x86_intel>]}
 
+cir.func @linkage_attr() {
+  cir.return {cir.test = [#cir.linkage<external>,
+                          #cir.linkage<linkonce_odr>,
+                          #cir.linkage<cir_private>]}
+}
+
+// CHECK: cir.func @linkage_attr() {
+// CHECK:   cir.return {cir.test = [#cir.linkage<external>, #cir.linkage<linkonce_odr>, #cir.linkage<cir_private>]}
+
+cir.func @calling_conv_attr() {
+  cir.return {cir.test = [#cir.calling_conv<c>, #cir.calling_conv<ptx_kernel>,
+                          #cir.calling_conv<amdgpu_kernel>]}
+}
+
+// CHECK: cir.func @calling_conv_attr() {
+// CHECK:   cir.return {cir.test = [#cir.calling_conv<c>, #cir.calling_conv<ptx_kernel>, #cir.calling_conv<amdgpu_kernel>]}
+
+cir.func @side_effect_attr() {
+  cir.return {cir.test = [#cir.side_effect<all>, #cir.side_effect<pure>,
+                          #cir.side_effect<const>]}
+}
+
+// CHECK: cir.func @side_effect_attr() {
+// CHECK:   cir.return {cir.test = [#cir.side_effect<all>, #cir.side_effect<pure>, #cir.side_effect<const>]}
+
 // The operations themselves keep printing a bare keyword.
 cir.func @operations_print_bare_keywords(%arg0: !s32i, %arg1: !s32i,
                                          %arg2: !cir.ptr<!s32i>) {
@@ -133,4 +158,10 @@ cir.func @operations_print_bare_keywords(%arg0: !s32i, %arg1: !s32i,
 // CHECK:   %2 = cir.load syncscope(system) atomic(seq_cst) %arg2 : !cir.ptr<!s32i>, !s32i
 // CHECK:   cir.atomic.fence syncscope(system) seq_cst
 
+// cir.global's linkage is the one bare keyword that cannot be checked from
+// inside a function.
+cir.global "private" internal @g = #cir.int<0> : !s32i
+
+// CHECK: cir.global "private" internal @g = #cir.int<0> : !s32i
+
 }



More information about the llvm-branch-commits mailing list