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 ();
+}

Reply via email to