https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/220888
cir.is_fp_class printed its flags inconsistently. One of the ten single-bit values came out bare, as in `fcSNan`, while every group value and every multi-flag combination came out quoted, as in `"fcInf"` and `"fcSNan|fcNegInf"`. That split comes from I32BitEnumAttr setting printBitEnumQuoted, which EnumAttr.td marks as kept only for backwards compatibility. The bit makes the printer quote anything that is not a single bit. Clearing printBitEnumQuoted and using the `enum` directive selects the separator-aware parser and printer, so every value now spells unquoted: cir.is_fp_class %x, fcInf : (!cir.float) -> !cir.bool cir.is_fp_class %x, fcSNan|fcNegInf : (!cir.float) -> !cir.bool The enum also drops its specialized IntegerAttr in favour of a CIR_EnumAttr wrapper, like the rest of the stack, giving it a standalone spelling of `#cir.fp_class<fcSNan|fcNegInf>`. The wrapper is named CIR_FPClassTestAttr rather than after the FPClassTestEnum def, since CIRLoweringEmitter derives the C++ class name from the def name. This is the only commit in the stack that changes operation syntax, so it updates 37 CHECK lines across the three builtin tests. --- Stacked on #220887. Based on `users/xlauko/cir-enum-08-linkage-cc-side-effect`, so the diff shown is this commit alone. >From 6ea490b8b68e521fece512331e6adb1bf999eb50 Mon Sep 17 00:00:00 2001 From: Henrich Lauko <[email protected]> Date: Thu, 3 Sep 2026 11:29:23 +0000 Subject: [PATCH] [CIR] Migrate the FPClassTest bit enum and unquote its flags cir.is_fp_class printed its flags inconsistently. One of the ten single-bit values came out bare, as in `fcSNan`, while every group value and every multi-flag combination came out quoted, as in `"fcInf"` and `"fcSNan|fcNegInf"`. That split comes from I32BitEnumAttr setting printBitEnumQuoted, which EnumAttr.td marks as kept only for backwards compatibility. The bit makes the printer quote anything that is not a single bit. Clearing printBitEnumQuoted and using the `enum` directive selects the separator-aware parser and printer, so every value now spells unquoted: cir.is_fp_class %x, fcInf : (!cir.float) -> !cir.bool cir.is_fp_class %x, fcSNan|fcNegInf : (!cir.float) -> !cir.bool The enum also drops its specialized IntegerAttr in favour of a CIR_EnumAttr wrapper, like the rest of the stack, giving it a standalone spelling of `#cir.fp_class<fcSNan|fcNegInf>`. The wrapper is named CIR_FPClassTestAttr rather than after the FPClassTestEnum def, since CIRLoweringEmitter derives the C++ class name from the def name. This is the only commit in the stack that changes operation syntax, so it updates 37 CHECK lines across the three builtin tests. --- 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, 67 insertions(+), 41 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index ad4e6600cddf1..4fe1c5a696e1d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -6955,8 +6955,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"; @@ -6983,10 +6993,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 aafc58e792678..da6d2e59dbda9 100644 --- a/clang/test/CIR/IR/enum-attrs.cir +++ b/clang/test/CIR/IR/enum-attrs.cir @@ -142,21 +142,37 @@ cir.func @side_effect_attr() { // CHECK: cir.func @side_effect_attr() { // CHECK: cir.return {cir.test = [#cir.side_effect<all>, #cir.side_effect<pure>, #cir.side_effect<const>]} +// A bit enum, so a value can name several flags. +cir.func @fp_class_attr() { + cir.return {cir.test = [#cir.fp_class<fcNone>, + #cir.fp_class<fcSNan>, + #cir.fp_class<fcInf>, + #cir.fp_class<fcSNan|fcNegInf>]} +} + +// CHECK: 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>]} + // The operations themselves keep printing a bare keyword. cir.func @operations_print_bare_keywords(%arg0: !s32i, %arg1: !s32i, - %arg2: !cir.ptr<!s32i>) { + %arg2: !cir.ptr<!s32i>, + %arg3: !cir.float) { %0 = cir.cast bitcast %arg0 : !s32i -> !s32i %1 = cir.cmp lt %arg0, %arg1 : !s32i %2 = cir.load syncscope(system) atomic(seq_cst) %arg2 : !cir.ptr<!s32i>, !s32i cir.atomic.fence syncscope(system) seq_cst + %3 = cir.is_fp_class %arg3, fcInf : (!cir.float) -> !cir.bool + %4 = cir.is_fp_class %arg3, fcSNan|fcNegInf : (!cir.float) -> !cir.bool cir.return } -// CHECK: cir.func @operations_print_bare_keywords(%arg0: !s32i, %arg1: !s32i, %arg2: !cir.ptr<!s32i>) { +// CHECK: cir.func @operations_print_bare_keywords(%arg0: !s32i, %arg1: !s32i, %arg2: !cir.ptr<!s32i>, %arg3: !cir.float) { // CHECK: %0 = cir.cast bitcast %arg0 : !s32i -> !s32i // CHECK: %1 = cir.cmp lt %arg0, %arg1 : !s32i // CHECK: %2 = cir.load syncscope(system) atomic(seq_cst) %arg2 : !cir.ptr<!s32i>, !s32i // CHECK: cir.atomic.fence syncscope(system) seq_cst +// CHECK: %3 = cir.is_fp_class %arg3, fcInf : (!cir.float) -> !cir.bool +// CHECK: %4 = cir.is_fp_class %arg3, fcSNan|fcNegInf : (!cir.float) -> !cir.bool // cir.global's linkage is the one bare keyword that cannot be checked from // inside a function. _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
