[gcc r12-11155] builtins: Fix up DFP ICEs on __builtin_fpclassify [PR102674]
Jakub Jelinek
jakub@gcc.gnu.org
Fri Jun 13 15:40:47 GMT 2025
https://gcc.gnu.org/g:573500a654aaf96227838a24b311a58a9a812610
commit r12-11155-g573500a654aaf96227838a24b311a58a9a812610
Author: Jakub Jelinek <jakub@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 <jakub@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.
(cherry picked from commit 5bb36d832c955e575bd458a02f3c6c5b28564aed)
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 dc350246fb17..57fb1f7d2489 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -9008,29 +9008,34 @@ 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))
{
real_inf (&r);
tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
- build_real (type, r));
+ build_real (type, r));
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 ();
+}
More information about the Gcc-cvs
mailing list