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

>From 08e34faa3b8ecdb430c69e6e72b14db369e2f5e0 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <[email protected]>
Date: Thu, 3 Sep 2026 12:44:31 +0000
Subject: [PATCH 1/2] [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              | 28 +++++++++++++++++++
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td 
b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index fc10268fba693..f08a127dcd192 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -1964,8 +1964,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 33ecf34b8f960..c9e5ecc69fa58 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3345,7 +3345,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
@@ -3411,7 +3416,7 @@ def CIR_GlobalOp : CIR_RegionBranchOpBase<"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,
@@ -3437,7 +3442,7 @@ def CIR_GlobalOp : CIR_RegionBranchOpBase<"global", [
     ($sym_visibility^)?
     ($global_visibility^)?
     (`constant` $constant^)?
-    $linkage
+    enum($linkage)
     (`comdat` $comdat^)?
     (`tls_model` `=` enum($tls_model)^)?
     (`tls_refs` `=` $tls_refs^)?
@@ -4202,7 +4207,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,
@@ -4296,11 +4305,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,
@@ -4308,7 +4317,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,
@@ -4612,7 +4621,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 53983a5c2cf2c..2e675c2681b94 100644
--- a/clang/test/CIR/IR/enum-attrs.cir
+++ b/clang/test/CIR/IR/enum-attrs.cir
@@ -105,6 +105,28 @@ cir.func @asm_flavor_attr() {
                           #cir.asm_flavor<x86_intel>]}
 }
 
+// CHECK-LABEL: cir.func @linkage_attr() {
+cir.func @linkage_attr() {
+  // CHECK: cir.return {cir.test = [#cir.linkage<external>, 
#cir.linkage<linkonce_odr>, #cir.linkage<cir_private>]}
+  cir.return {cir.test = [#cir.linkage<external>,
+                          #cir.linkage<linkonce_odr>,
+                          #cir.linkage<cir_private>]}
+}
+
+// CHECK-LABEL: cir.func @calling_conv_attr() {
+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.return {cir.test = [#cir.calling_conv<c>, #cir.calling_conv<ptx_kernel>,
+                          #cir.calling_conv<amdgpu_kernel>]}
+}
+
+// CHECK-LABEL: cir.func @side_effect_attr() {
+cir.func @side_effect_attr() {
+  // CHECK: cir.return {cir.test = [#cir.side_effect<all>, 
#cir.side_effect<pure>, #cir.side_effect<const>]}
+  cir.return {cir.test = [#cir.side_effect<all>, #cir.side_effect<pure>,
+                          #cir.side_effect<const>]}
+}
+
 // The operations themselves keep printing a bare keyword.
 
 // CHECK-LABEL: cir.func @mem_order_sync_scope_ops(%arg0: !cir.ptr<!s32i>) {
@@ -116,4 +138,10 @@ cir.func @mem_order_sync_scope_ops(%arg0: !cir.ptr<!s32i>) 
{
   cir.return
 }
 
+// cir.global's linkage is the one bare keyword that cannot be checked from
+// inside a function.
+
+// CHECK-LABEL: cir.global "private" internal @g = #cir.int<0> : !s32i
+cir.global "private" internal @g = #cir.int<0> : !s32i
+
 }

>From a619b6d45e462751dd21d6a1ecdd8e64e272dcd1 Mon Sep 17 00:00:00 2001
From: Henrich Lauko <[email protected]>
Date: Thu, 3 Sep 2026 12:44:31 +0000
Subject: [PATCH 2/2] [CIR] Migrate the FPClassTest bit enum and unquote its
 flags

cir.is_fp_class printed its flags inconsistently. Single-bit values came out
bare, as in `fcSNan`, while group values and combinations came out quoted, as
in `"fcInf"` and `"fcSNan|fcNegInf"`. That comes from I32BitEnumAttr setting
printBitEnumQuoted, which EnumAttr.td keeps only for backwards compatibility.

Clearing the bit and using the `enum` directive selects the separator-aware
parser and printer, so every value now spells unquoted:

  cir.is_fp_class %x, fcSNan|fcNegInf : (!cir.float) -> !cir.bool

The enum also drops its specialized IntegerAttr for a CIR_EnumAttr wrapper,
giving it the standalone spelling `#cir.fp_class<fcSNan|fcNegInf>`. This
changes operation syntax, so it updates 37 CHECK lines.
---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 14 ++++++-
 .../CIR/CodeGenBuiltins/builtin-fpclassify.c  | 40 +++++++++----------
 .../CIR/CodeGenBuiltins/builtin-isfpclass.c   | 32 +++++++--------
 .../CIR/CodeGenBuiltins/builtin-isinf-sign.c  |  2 +-
 clang/test/CIR/IR/enum-attrs.cir              | 20 ++++++++++
 5 files changed, 69 insertions(+), 39 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index c9e5ecc69fa58..0606911883ad6 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -6987,8 +6987,18 @@ def FPClassTestEnum
   FPClass_Sub, FPClass_Zero, FPClass_PosFin, FPClass_NegFin, FPClass_Fin,
   FPClass_Pos, FPClass_Neg, FPClass_All]> {
   let printBitEnumPrimaryGroups = 1;
+
+  // I32BitEnumAttr turns this on for backwards compatibility, which makes the
+  // operation printer quote every value that is not a single bit. Turning it
+  // off, together with the `enum` directive on cir.is_fp_class, gets a
+  // separator-aware parser and printer that spell every value unquoted.
+  let printBitEnumQuoted = 0;
+
+  let genSpecializedAttr = 0;
 }
 
+def CIR_FPClassTestAttr : CIR_EnumAttr<FPClassTestEnum, "fp_class">;
+
 def CIR_IsFPClassOp : CIR_Op<"is_fp_class", [Pure]> {
   let summary = "Corresponding to the `__builtin_fpclassify` builtin function 
in clang";
 
@@ -7015,10 +7025,10 @@ def CIR_IsFPClassOp : CIR_Op<"is_fp_class", [Pure]> {
   }];
 
   let arguments = (ins CIR_AnyFloatType:$src,
-                       FPClassTestEnum:$flags);
+                       CIR_FPClassTestAttr:$flags);
   let results = (outs CIR_BoolType:$result);
   let assemblyFormat = [{
-    $src `,` $flags `:` functional-type($src, $result) attr-dict
+    $src `,` enum($flags) `:` functional-type($src, $result) attr-dict
   }];
 }
 
diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c 
b/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c
index abdfe67e8527c..780f242bbef59 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c
+++ b/clang/test/CIR/CodeGenBuiltins/builtin-fpclassify.c
@@ -15,16 +15,16 @@ void test_fpclassify_nan(){
     float nanValue = 0.0f / 0.0f;
     __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
                                          FP_SUBNORMAL, FP_ZERO, nanValue);
-// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, "fcZero" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, fcZero : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_ZERO]], true {
 // CIR: cir.const #cir.int<96> : !s32i
-// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, "fcNan" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, fcNan : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_NAN]], true {
 // CIR: cir.const #cir.int<3> : !s32i
-// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, "fcInf" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, fcInf : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_INF]], true {
 // CIR: cir.const #cir.int<516> : !s32i
-// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, "fcNormal" : (!cir.float) 
-> !cir.bool
+// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, fcNormal : (!cir.float) 
-> !cir.bool
 // CIR: %[[NORMAL_VAL:.+]] = cir.const #cir.int<264> : !s32i
 // CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
 // CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else 
%[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
@@ -84,16 +84,16 @@ void test_fpclassify_inf(){
     float infValue = 1.0f / 0.0f;
     __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
                                          FP_SUBNORMAL, FP_ZERO, infValue);
-// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, "fcZero" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, fcZero : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_ZERO]], true {
 // CIR: cir.const #cir.int<96> : !s32i
-// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, "fcNan" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, fcNan : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_NAN]], true {
 // CIR: cir.const #cir.int<3> : !s32i
-// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, "fcInf" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, fcInf : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_INF]], true {
 // CIR: cir.const #cir.int<516> : !s32i
-// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, "fcNormal" : (!cir.float) 
-> !cir.bool
+// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, fcNormal : (!cir.float) 
-> !cir.bool
 // CIR: %[[NORMAL_VAL:.+]] = cir.const #cir.int<264> : !s32i
 // CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
 // CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else 
%[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
@@ -152,16 +152,16 @@ void test_fpclassify_normal(){
     float normalValue = 1.0f;
     __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
                                             FP_SUBNORMAL, FP_ZERO, 
normalValue);
-// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, "fcZero" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, fcZero : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_ZERO]], true {
 // CIR: cir.const #cir.int<96> : !s32i
-// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, "fcNan" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, fcNan : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_NAN]], true {
 // CIR: cir.const #cir.int<3> : !s32i
-// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, "fcInf" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, fcInf : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_INF]], true {
 // CIR: cir.const #cir.int<516> : !s32i
-// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, "fcNormal" : (!cir.float) 
-> !cir.bool
+// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, fcNormal : (!cir.float) 
-> !cir.bool
 // CIR: %[[NORMAL_VAL:.+]] = cir.const #cir.int<264> : !s32i
 // CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
 // CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else 
%[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
@@ -221,16 +221,16 @@ void test_fpclassify_subnormal(){
     float subnormalValue = 1.0e-40f;
     __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
                                                FP_SUBNORMAL, FP_ZERO, 
subnormalValue);
-// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, "fcZero" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, fcZero : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_ZERO]], true {
 // CIR: cir.const #cir.int<96> : !s32i
-// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, "fcNan" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, fcNan : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_NAN]], true {
 // CIR: cir.const #cir.int<3> : !s32i
-// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, "fcInf" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, fcInf : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_INF]], true {
 // CIR: cir.const #cir.int<516> : !s32i
-// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, "fcNormal" : (!cir.float) 
-> !cir.bool
+// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, fcNormal : (!cir.float) 
-> !cir.bool
 // CIR: %[[NORMAL_VAL:.+]] = cir.const #cir.int<264> : !s32i
 // CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
 // CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else 
%[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
@@ -290,16 +290,16 @@ void test_fpclassify_zero(){
     float zeroValue = 0.0f;
     __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
                                           FP_SUBNORMAL, FP_ZERO, zeroValue);
-// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, "fcZero" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_ZERO:.+]] = cir.is_fp_class %{{.+}}, fcZero : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_ZERO]], true {
 // CIR: cir.const #cir.int<96> : !s32i
-// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, "fcNan" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_NAN:.+]] = cir.is_fp_class %{{.+}}, fcNan : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_NAN]], true {
 // CIR: cir.const #cir.int<3> : !s32i
-// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, "fcInf" : (!cir.float) -> 
!cir.bool
+// CIR: %[[IS_INF:.+]] = cir.is_fp_class %{{.+}}, fcInf : (!cir.float) -> 
!cir.bool
 // CIR: cir.ternary(%[[IS_INF]], true {
 // CIR: cir.const #cir.int<516> : !s32i
-// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, "fcNormal" : (!cir.float) 
-> !cir.bool
+// CIR: %[[IS_NORMAL:.+]] = cir.is_fp_class %{{.+}}, fcNormal : (!cir.float) 
-> !cir.bool
 // CIR: %[[NORMAL_VAL:.+]] = cir.const #cir.int<264> : !s32i
 // CIR: %[[SUBNORMAL_VAL:.+]] = cir.const #cir.int<144> : !s32i
 // CIR: cir.select if %[[IS_NORMAL]] then %[[NORMAL_VAL]] else 
%[[SUBNORMAL_VAL]] : (!cir.bool, !s32i, !s32i) -> !s32i
diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-isfpclass.c 
b/clang/test/CIR/CodeGenBuiltins/builtin-isfpclass.c
index 880e5e444aff8..6157a3c293a5f 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtin-isfpclass.c
+++ b/clang/test/CIR/CodeGenBuiltins/builtin-isfpclass.c
@@ -10,55 +10,55 @@ int finite(double);
 void test_is_finite(__fp16 *H, float F, double D, long double LD) {
     volatile int res;
     res = __builtin_isinf(*H);
-    // CIR: cir.is_fp_class %{{.*}}, "fcInf" : (!cir.f16) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcInf : (!cir.f16) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f16(half {{.*}}, /* (inf) */ i32 516)
     // OGCG: call i1 @llvm.is.fpclass.f16(half {{.*}}, /* (inf) */ i32 516)
 
     res = __builtin_isinf(F);
-    // CIR: cir.is_fp_class %{{.*}}, "fcInf" : (!cir.float) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcInf : (!cir.float) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (inf) */ i32 516)
     // OGCG: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (inf) */ i32 516)
 
     res = __builtin_isinf(D);
-    // CIR: cir.is_fp_class %{{.*}}, "fcInf" : (!cir.double) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcInf : (!cir.double) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f64(double {{.*}}, /* (inf) */ i32 516)
     // OGCG: call i1 @llvm.is.fpclass.f64(double {{.*}}, /* (inf) */ i32 516)
 
     res = __builtin_isinf(LD);
-    // CIR: cir.is_fp_class %{{.*}}, "fcInf" : (!cir.long_double<!cir.f80>) -> 
!cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcInf : (!cir.long_double<!cir.f80>) -> 
!cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f80(x86_fp80 {{.*}}, /* (inf) */ i32 516)
     // OGCG: call i1 @llvm.is.fpclass.f80(x86_fp80 {{.*}}, /* (inf) */ i32 516)
 
     res = __builtin_isfinite(*H);
-    // CIR: cir.is_fp_class %{{.*}}, "fcFinite" : (!cir.f16) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcFinite : (!cir.f16) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f16(half {{.*}}, /* (zero sub norm) */ 
i32 504)
     // OGCG: call i1 @llvm.is.fpclass.f16(half {{.*}}, /* (zero sub norm) */ 
i32 504)
 
     res = __builtin_isfinite(F);
-    // CIR: cir.is_fp_class %{{.*}}, "fcFinite" : (!cir.float) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcFinite : (!cir.float) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (zero sub norm) */ 
i32 504)
     // OGCG: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (zero sub norm) */ 
i32 504)
 
     res = finite(D);
-    // CIR: cir.is_fp_class %{{.*}}, "fcFinite" : (!cir.double) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcFinite : (!cir.double) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f64(double {{.*}}, /* (zero sub norm) */ 
i32 504)
     // OGCG: call i1 @llvm.is.fpclass.f64(double %20, /* (zero sub norm) */ 
i32 504)
     res = __builtin_isnormal(*H);
-    // CIR: cir.is_fp_class %{{.*}}, "fcNormal" : (!cir.f16) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcNormal : (!cir.f16) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f16(half {{.*}}, /* (norm) */ i32 264)
     // OGCG: call i1 @llvm.is.fpclass.f16(half {{.*}}, /* (norm) */ i32 264)
 
     res = __builtin_isnormal(F);
-    // CIR: cir.is_fp_class %{{.*}}, "fcNormal" : (!cir.float) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcNormal : (!cir.float) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (norm) */ i32 264)
     // OGCG: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (norm) */ i32 264)
 
     res = __builtin_issubnormal(F);
-    // CIR: cir.is_fp_class %{{.*}}, "fcSubnormal" : (!cir.float) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcSubnormal : (!cir.float) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (sub) */ i32 144)
     // OGCG: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (sub) */ i32 144)
     res = __builtin_iszero(F);
-    // CIR: cir.is_fp_class %{{.*}}, "fcZero" : (!cir.float) -> !cir.bool
+    // CIR: cir.is_fp_class %{{.*}}, fcZero : (!cir.float) -> !cir.bool
     // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (zero) */ i32 96)
     // OGCG: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (zero) */ i32 96)
     res = __builtin_issignaling(F);
@@ -72,7 +72,7 @@ _Bool check_isfpclass_finite(float x) {
 }
 
 // CIR: cir.func {{.*}}@check_isfpclass_finite
-// CIR: cir.is_fp_class %{{.*}}, "fcFinite" : (!cir.float)
+// CIR: cir.is_fp_class %{{.*}}, fcFinite : (!cir.float)
 // LLVM: @check_isfpclass_finite
 // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (zero sub norm) */ i32 
504)
 // OGCG: @check_isfpclass_finite
@@ -83,7 +83,7 @@ _Bool check_isfpclass_nan_f32(float x) {
 }
 
 // CIR: cir.func {{.*}}@check_isfpclass_nan_f32
-// CIR: cir.is_fp_class %{{.*}}, "fcNan" : (!cir.float)
+// CIR: cir.is_fp_class %{{.*}}, fcNan : (!cir.float)
 // LLVM: @check_isfpclass_nan_f32
 // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (nan) */ i32 3)
 // OGCG: @check_isfpclass_nan_f32
@@ -107,7 +107,7 @@ _Bool check_isfpclass_zero_f16(_Float16 x) {
 }
 
 // CIR: cir.func {{.*}}@check_isfpclass_zero_f16
-// CIR: cir.is_fp_class %{{.*}}, "fcZero" : (!cir.f16)
+// CIR: cir.is_fp_class %{{.*}}, fcZero : (!cir.f16)
 // LLVM: @check_isfpclass_zero_f16
 // LLVM: call i1 @llvm.is.fpclass.f16(half {{.*}}, /* (zero) */ i32 96)
 // OGCG: @check_isfpclass_zero_f16
@@ -118,7 +118,7 @@ _Bool check_isfpclass_snan_neginf(double x) {
 }
 
 // CIR: cir.func {{.*}}@check_isfpclass_snan_neginf
-// CIR: cir.is_fp_class %{{.*}}, "fcSNan|fcNegInf" : (!cir.double)
+// CIR: cir.is_fp_class %{{.*}}, fcSNan|fcNegInf : (!cir.double)
 // LLVM: @check_isfpclass_snan_neginf
 // LLVM: call i1 @llvm.is.fpclass.f64(double {{.*}}, /* (snan ninf) */ i32 5)
 // OGCG: @check_isfpclass_snan_neginf
@@ -129,7 +129,7 @@ _Bool check_isfpclass_multi(float x) {
 }
 
 // CIR: cir.func {{.*}}@check_isfpclass_multi
-// CIR: cir.is_fp_class %{{.*}}, "fcNegative|fcPositive|fcQNan" : (!cir.float)
+// CIR: cir.is_fp_class %{{.*}}, fcNegative|fcPositive|fcQNan : (!cir.float)
 // LLVM: @check_isfpclass_multi
 // LLVM: call i1 @llvm.is.fpclass.f32(float {{.*}}, /* (qnan inf zero sub 
norm) */ i32 1022)
 // OGCG: @check_isfpclass_multi
diff --git a/clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c 
b/clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c
index 91c2e13096dc4..ffe9bea037391 100644
--- a/clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c
+++ b/clang/test/CIR/CodeGenBuiltins/builtin-isinf-sign.c
@@ -8,7 +8,7 @@
 int test_float_isinf_sign(float x) {
   // CIR-LABEL: test_float_isinf_sign
   // CIR: %[[ARG:.*]] = cir.load align(4) %{{.*}} : !cir.ptr<!cir.float>, 
!cir.float
-  // CIR: %[[IS_INF:.*]] = cir.is_fp_class %[[ARG]], "fcInf" : (!cir.float) -> 
!cir.bool
+  // CIR: %[[IS_INF:.*]] = cir.is_fp_class %[[ARG]], fcInf : (!cir.float) -> 
!cir.bool
   // CIR: %[[IS_NEG:.*]] = cir.signbit %[[ARG]] : !cir.float -> !cir.bool
   // CIR: %[[C_0:.*]] = cir.const #cir.int<0> : !s32i
   // CIR: %[[C_1:.*]] = cir.const #cir.int<1> : !s32i
diff --git a/clang/test/CIR/IR/enum-attrs.cir b/clang/test/CIR/IR/enum-attrs.cir
index 2e675c2681b94..e3979fcd138f4 100644
--- a/clang/test/CIR/IR/enum-attrs.cir
+++ b/clang/test/CIR/IR/enum-attrs.cir
@@ -127,6 +127,17 @@ cir.func @side_effect_attr() {
                           #cir.side_effect<const>]}
 }
 
+// A bit enum, so a value can name several flags.
+
+// CHECK-LABEL: cir.func @fp_class_attr() {
+cir.func @fp_class_attr() {
+  // CHECK: cir.return {cir.test = [#cir.fp_class<fcNone>, 
#cir.fp_class<fcSNan>, #cir.fp_class<fcInf>, #cir.fp_class<fcSNan|fcNegInf>]}
+  cir.return {cir.test = [#cir.fp_class<fcNone>,
+                          #cir.fp_class<fcSNan>,
+                          #cir.fp_class<fcInf>,
+                          #cir.fp_class<fcSNan|fcNegInf>]}
+}
+
 // The operations themselves keep printing a bare keyword.
 
 // CHECK-LABEL: cir.func @mem_order_sync_scope_ops(%arg0: !cir.ptr<!s32i>) {
@@ -138,6 +149,15 @@ cir.func @mem_order_sync_scope_ops(%arg0: !cir.ptr<!s32i>) 
{
   cir.return
 }
 
+// CHECK-LABEL: cir.func @fp_class_ops(%arg0: !cir.float) {
+cir.func @fp_class_ops(%arg0: !cir.float) {
+  // CHECK: %0 = cir.is_fp_class %arg0, fcInf : (!cir.float) -> !cir.bool
+  %0 = cir.is_fp_class %arg0, fcInf : (!cir.float) -> !cir.bool
+  // CHECK: %1 = cir.is_fp_class %arg0, fcSNan|fcNegInf : (!cir.float) -> 
!cir.bool
+  %1 = cir.is_fp_class %arg0, fcSNan|fcNegInf : (!cir.float) -> !cir.bool
+  cir.return
+}
+
 // cir.global's linkage is the one bare keyword that cannot be checked from
 // inside a function.
 

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to