https://gcc.gnu.org/g:5bb36d832c955e575bd458a02f3c6c5b28564aed
commit r15-5672-g5bb36d832c955e575bd458a02f3c6c5b28564aed Author: Jakub Jelinek <ja...@redhat.com> Date: Tue Nov 26 09:46:51 2024 +0100 builtins: Fix up DFP ICEs on __builtin_fpclassify [PR102674] 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. 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. Diff: --- gcc/builtins.cc | 23 ++++++++----- gcc/testsuite/gcc.dg/dfp/pr102674.c | 65 +++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 055b31d264ca..6271cdc1debb 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -9837,28 +9837,33 @@ fold_builtin_fpclassify (location_t loc, tree *args, int nargs) (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; diff --git a/gcc/testsuite/gcc.dg/dfp/pr102674.c b/gcc/testsuite/gcc.dg/dfp/pr102674.c new file mode 100644 index 000000000000..c67ecf5ce71b --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pr102674.c @@ -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 (); +}