[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