On Tue, 26 Nov 2024, Jakub Jelinek wrote: > 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?
OK. Thanks, Richard. > 2024-11-26 Jakub Jelinek <[email protected]> > > 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 > > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
