https://github.com/xlauko updated https://github.com/llvm/llvm-project/pull/220888
>From d1fb42b59edb04204cb3fc10da9b5da95fbccf89 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 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 632b107402a19..cd0a401d9b77f 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -6993,8 +6993,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"; @@ -7021,10 +7031,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
