[PATCH] gimple-fold: Don't optimize wierdo floating point value reads [PR95450]
Richard Biener
rguenther@suse.de
Mon Aug 24 10:51:25 GMT 2020
On Wed, 12 Aug 2020, Jakub Jelinek wrote:
> On Wed, Aug 12, 2020 at 04:30:35PM +0200, Richard Biener wrote:
> > Not a final review but if we care for this kind of normalization at all
> > the we should do so consistently, thus for both encode and interpret and
> > for all modes. For FP we could also check if we'd consider the values
> > equal rather than whether we would en/decode them to the same bit pattern
> > (which might or might not be what an actual ISA gpr<->fpr reg move would
> > do)
>
> I think the verification that what we encode can be interpreted back
> woiuld be only an internal consistency check (so perhaps for ENABLE_CHECKING
> if flag_checking only, but if both directions perform it, then we need
> to avoid mutual recursion).
> While for the other direction (interpretation), at least for the broken by
> design long doubles we just know we can't represent in GCC all valid values.
> The other floating point formats are just theoretical case, perhaps we would
> canonicalize something to a value that wouldn't trigger invalid exception
> when without canonicalization it would trigger it at runtime, so let's just
> ignore those.
>
> Adjusted (so far untested) patch to do it in native_interpret_real instead
> and limit it to the MODE_COMPOSITE_P cases, for which e.g.
> fold-const.c/simplify-rtx.c punts in several other places too because we just
> know we can't represent everything.
>
> E.g.
> /* Don't constant fold this floating point operation if the
> result may dependent upon the run-time rounding mode and
> flag_rounding_math is set, or if GCC's software emulation
> is unable to accurately represent the result. */
> if ((flag_rounding_math
> || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
> && (inexact || !real_identical (&result, &value)))
> return NULL_TREE;
> Or perhaps guard it with MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations
> too, thus break what gnulib / m4 does with -ffast-math, but not normally?
OK.
Richard.
> 2020-08-12 Jakub Jelinek <jakub@redhat.com>
>
> PR target/95450
> * fold-const.c (native_interpret_real): For MODE_COMPOSITE_P modes
> punt if the to be returned REAL_CST does not encode to the bitwise
> same representation.
>
> * gcc.target/powerpc/pr95450.c: New test.
>
> --- gcc/fold-const.c.jj 2020-08-04 10:02:43.434408528 +0200
> +++ gcc/fold-const.c 2020-08-12 17:16:31.893226663 +0200
> @@ -8327,7 +8327,19 @@ native_interpret_real (tree type, const
> }
>
> real_from_target (&r, tmp, mode);
> - return build_real (type, r);
> + tree ret = build_real (type, r);
> + if (MODE_COMPOSITE_P (mode))
> + {
> + /* For floating point values in composite modes, punt if this folding
> + doesn't preserve bit representation. As the mode doesn't have fixed
> + precision while GCC pretends it does, there could be valid values that
> + GCC can't really represent accurately. See PR95450. */
> + unsigned char buf[24];
> + if (native_encode_expr (ret, buf, total_bytes, 0) != total_bytes
> + || memcmp (ptr, buf, total_bytes) != 0)
> + ret = NULL_TREE;
> + }
> + return ret;
> }
>
>
> --- gcc/testsuite/gcc.target/powerpc/pr95450.c.jj 2020-08-12 17:10:51.402872241 +0200
> +++ gcc/testsuite/gcc.target/powerpc/pr95450.c 2020-08-12 17:10:51.402872241 +0200
> @@ -0,0 +1,29 @@
> +/* PR target/95450 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-not "return \[0-9.e+]\+;" "optimized" } } */
> +
> +/* Verify this is not optimized for double double into return floating_point_constant,
> + as while that constant is the maximum normalized floating point value, it needs
> + 107 bit precision, which is more than GCC supports for this format. */
> +
> +#if __LDBL_MANT_DIG__ == 106
> +union U
> +{
> + struct { double hi; double lo; } dd;
> + long double ld;
> +};
> +
> +const union U g = { { __DBL_MAX__, __DBL_MAX__ / (double)134217728UL / (double)134217728UL } };
> +#else
> +struct S
> +{
> + long double ld;
> +} g;
> +#endif
> +
> +long double
> +foo (void)
> +{
> + return g.ld;
> +}
>
>
> Jakub
>
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
More information about the Gcc-patches
mailing list