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 <ja...@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 <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)