[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 04:31:17 PDT 2026
https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/220887
The last of the I32EnumAttr-backed operation enums, apart from the bit enum
handled next. Each sets genSpecializedAttr = 0 and gains a CIR_EnumAttr
wrapper, and cir.global wraps $linkage in `enum()`.
cir.func and cir.call print all three through hand-written code, but they
stream stringifyGlobalLinkageKind(getLinkage()) and friends. Those take the
enum rather than the attribute, so the sites are unchanged. The
DefaultValuedAttr defaults for $linkage, $calling_conv and $side_effect keep
taking the same C++ expressions.
Operation syntax is unchanged, so no test needed updating.
GlobalLinkageKind's wrapper is spelled `#cir.linkage<internal>`, dropping
both the `global_` prefix and the `_kind` suffix that the enum class name
carries for C++ reasons.
---
Stacked on #220885. Based on `users/xlauko/cir-enum-07-assume-atomic-asm`, so the diff shown is this commit alone.
>From cedbf0bd5b5684574cdea851ee7e792fc412fc7f Mon Sep 17 00:00:00 2001
From: Henrich Lauko <hlauko at nvidia.com>
Date: Thu, 3 Sep 2026 11:29:23 +0000
Subject: [PATCH] [CIR] Migrate GlobalLinkageKind, CallingConv and SideEffect
off IntegerAttr
The last of the I32EnumAttr-backed operation enums, apart from the bit enum
handled next. Each sets genSpecializedAttr = 0 and gains a CIR_EnumAttr
wrapper, and cir.global wraps $linkage in `enum()`.
cir.func and cir.call print all three through hand-written code, but they
stream stringifyGlobalLinkageKind(getLinkage()) and friends. Those take the
enum rather than the attribute, so the sites are unchanged. The
DefaultValuedAttr defaults for $linkage, $calling_conv and $side_effect keep
taking the same C++ expressions.
Operation syntax is unchanged, so no test needed updating.
GlobalLinkageKind's wrapper is spelled `#cir.linkage<internal>`, dropping
both the `global_` prefix and the `_kind` suffix that the enum class name
carries for C++ reasons.
---
.../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