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

Reply via email to