aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-11-26 09:46:51 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2024-11-26 09:46:51 +0100
commit5bb36d832c955e575bd458a02f3c6c5b28564aed (patch)
treee265fad04c99c66b9dcf00daefa4cd3207daa83d /gcc
parentf39e6b4f5cd4e5362cf4b1004a591df2c8b00304 (diff)
downloadgcc-5bb36d832c955e575bd458a02f3c6c5b28564aed.zip
gcc-5bb36d832c955e575bd458a02f3c6c5b28564aed.tar.gz
gcc-5bb36d832c955e575bd458a02f3c6c5b28564aed.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/builtins.cc23
-rw-r--r--gcc/testsuite/gcc.dg/dfp/pr102674.c65
2 files changed, 79 insertions, 9 deletions
diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 055b31d..6271cdc 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 0000000..c67ecf5
--- /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 ();
+}