Hi! This patch is similar to the one I've just posted, __builtin_fpclassify also needs to print decimal float minimum differently and use real_from_string3. Plus I've done some formatting fixes.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2024-11-26 Jakub Jelinek <ja...@redhat.com> PR middle-end/102674 * builtins.cc (fold_builtin_fpclassify): Use real_from_string3 rather than real_from_string. Use "1E%d" format string rather than "0x1p%d" for decimal float minimum. Formatting fixes. * gcc.dg/dfp/pr102674.c: New test. --- gcc/builtins.cc.jj 2024-11-25 14:15:55.923876729 +0100 +++ gcc/builtins.cc 2024-11-25 15:19:32.901016437 +0100 @@ -9837,28 +9837,33 @@ fold_builtin_fpclassify (location_t loc, (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */ tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, - build_real (type, dconst0)); + build_real (type, dconst0)); res = fold_build3_loc (loc, COND_EXPR, integer_type_node, - tmp, fp_zero, fp_subnormal); + tmp, fp_zero, fp_subnormal); - sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); - real_from_string (&r, buf); + if (DECIMAL_FLOAT_MODE_P (mode)) + sprintf (buf, "1E%d", REAL_MODE_FORMAT (mode)->emin - 1); + else + sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1); + real_from_string3 (&r, buf, mode); tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node, - arg, build_real (type, r)); - res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res); + arg, build_real (type, r)); + res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, + fp_normal, res); if (tree_expr_maybe_infinite_p (arg)) { tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg, - build_real (type, dconstinf)); + build_real (type, dconstinf)); res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, - fp_infinite, res); + fp_infinite, res); } if (tree_expr_maybe_nan_p (arg)) { tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg); - res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan); + res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, + res, fp_nan); } return res; --- gcc/testsuite/gcc.dg/dfp/pr102674.c.jj 2024-11-25 15:01:59.222877755 +0100 +++ gcc/testsuite/gcc.dg/dfp/pr102674.c 2024-11-25 15:08:50.827071775 +0100 @@ -0,0 +1,65 @@ +/* PR middle-end/102674 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 +#define FP_SUBNORMAL 3 +#define FP_NORMAL 4 + +__attribute__((noipa)) int +foo (_Decimal32 x) +{ + return __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, x); +} + +__attribute__((noipa)) int +bar (_Decimal64 x) +{ + return __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, x); +} + +__attribute__((noipa)) int +baz (_Decimal128 x) +{ + return __builtin_fpclassify (FP_NAN, FP_INFINITE, FP_NORMAL, + FP_SUBNORMAL, FP_ZERO, x); +} + +int +main () +{ + if (foo (__builtin_infd32 ()) != FP_INFINITE + || foo (-__builtin_infd32 ()) != FP_INFINITE + || foo (__builtin_nand32 ("")) != FP_NAN + || foo (9.999999E96DF) != FP_NORMAL + || foo (-1E-95DF) != FP_NORMAL + || foo (0.999999E-95DF) != FP_SUBNORMAL + || foo (-0.000001E-95DF) != FP_SUBNORMAL + || foo (0.000DF) != FP_ZERO + || foo (-0.00000DF) != FP_ZERO) + __builtin_abort (); + if (bar (__builtin_infd64 ()) != FP_INFINITE + || bar (-__builtin_infd64 ()) != FP_INFINITE + || bar (__builtin_nand64 ("")) != FP_NAN + || bar (9.999999999999999E384DD) != FP_NORMAL + || bar (-1E-383DD) != FP_NORMAL + || bar (0.999999999999999E-383DD) != FP_SUBNORMAL + || bar (-0.000000000000001E-383DD) != FP_SUBNORMAL + || bar (0.000DD) != FP_ZERO + || bar (-0.0000000000DD) != FP_ZERO) + __builtin_abort (); + if (baz (__builtin_infd128 ()) != FP_INFINITE + || baz (-__builtin_infd128 ()) != FP_INFINITE + || baz (__builtin_nand128 ("")) != FP_NAN + || baz (9.999999999999999999999999999999999E6144DL) != FP_NORMAL + || baz (-1E-6143DL) != FP_NORMAL + || baz (0.999999999999999999999999999999999E-6143DL) != FP_SUBNORMAL + || baz (-0.000000000000000000000000000000001E-6143DL) != FP_SUBNORMAL + || baz (0.000DL) != FP_ZERO + || baz (-0.0000000000000000000000DL) != FP_ZERO) + __builtin_abort (); +} Jakub