From f39e6b4f5cd4e5362cf4b1004a591df2c8b00304 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 26 Nov 2024 09:45:21 +0100 Subject: builtins: Fix up DFP ICEs on __builtin_is{inf,finite,normal} [PR43374] __builtin_is{inf,finite,normal} builtins ICE on _Decimal{32,64,128,64x} operands unless those operands are constant. The problem is that we fold the builtins to comparisons with the largest finite number, but a) get_max_float was only handling binary floats b) real_from_string again assumes binary float and so we were ICEing in the build_real called after the two calls. This patch adds decimal handling into get_max_float (well, moves it from c-cppbuiltin.cc which was printing those for __DEC{32,64,128}_MAX__ macros) and uses real_from_string3 (perhaps it is time to rename it to just real_from_string now that we can use function overloading) so that it handles both binary and decimal floats. 2024-11-26 Jakub Jelinek PR middle-end/43374 gcc/ * real.cc (get_max_float): Handle decimal float. * builtins.cc (fold_builtin_interclass_mathfn): Use real_from_string3 rather than real_from_string. Use "1E%d" format string rather than "0x1p%d" for decimal float minimum. gcc/c-family/ * c-cppbuiltin.cc (builtin_define_decimal_float_constants): Use get_max_float. gcc/testsuite/ * gcc.dg/dfp/pr43374.c: New test. --- gcc/c-family/c-cppbuiltin.cc | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'gcc/c-family') diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index 349918c..8fbfef5 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -357,17 +357,8 @@ builtin_define_decimal_float_constants (const char *name_prefix, /* Compute the maximum representable value. */ sprintf (name, "__%s_MAX__", name_prefix); - p = buf; - for (digits = fmt->p; digits; digits--) - { - *p++ = '9'; - if (digits == fmt->p) - *p++ = '.'; - } - *p = 0; - /* fmt->p plus 1, to account for the decimal point and fmt->emax - minus 1 because the digits are nines, not 1.0. */ - sprintf (&buf[fmt->p + 1], "E%d%s", fmt->emax - 1, suffix); + get_max_float (fmt, buf, sizeof (buf) - strlen (suffix), false); + strcat (buf, suffix); builtin_define_with_value (name, buf, 0); /* Compute epsilon (the difference between 1 and least value greater -- cgit v1.1