On Thu, 28 Oct 2021, Jakub Jelinek wrote:

> On Thu, Oct 28, 2021 at 01:32:17PM +0200, Richard Biener wrote:
> > diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
> > index f38b6d7d31c..a16395befcd 100644
> > --- a/gcc/simplify-rtx.c
> > +++ b/gcc/simplify-rtx.c
> > @@ -1917,6 +1917,19 @@ simplify_const_unary_operation (enum rtx_code code, 
> > machine_mode mode,
> >          return 0;
> >  
> >        d = real_value_truncate (mode, d);
> > +
> > +      /* Avoid the folding if flag_rounding_math is on and the
> > +    conversion is not exact.  */
> > +      if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
> > +   {
> > +     bool fail = false;
> > +     wide_int w = real_to_integer (&d, &fail,
> > +                                   GET_MODE_PRECISION
> > +                                     (as_a <scalar_int_mode> (op_mode)));
> > +     if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
> > +       return 0;
> > +   }
> > +
> >        return const_double_from_real_value (d, mode);
> >      }
> >    else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
> 
> What about the else if case (i.e. UNSIGNED_FLOAT)?

I'm not able to trigger unsigned_float to be used, even when
converting 0x8000000000000001 I get (float:DF (reg:DI...))
on x86_64 because we emit conditional code that will end up
using some compensation to emulate unsigned_float with
float with some tricks that do not necessarily look safe
from a rounding perspective (so maybe x86 would need to
resort to soft-fp here?):

        movabsq $4611686018427387905, %rax
        cvtsi2sdq       %rax, %xmm0
        addsd   %xmm0, %xmm0
        ucomisd .LC0(%rip), %xmm0

the constant is (0x8000000000000001u >> 1) | 1

> And I think it would be nice to test the simplify-rtx.c code somewhere,
> perhaps gcc/testsuite/gcc.dg/rtl/x86_64 testcase and check that we
> simplify with -frounding-math e.g. UNSIGNED_FLOAT from DImode
> 0x8000000000000000 or FLOAT or UNSIGNED_FLOAT from DImode
> 0x7ffffffffffffc00, but will not fold FLOAT or UNSIGNED_FLOAT from
> DImode 0x7ffffffffffffc01 or 0x7fffffffffffffff.

That it is not folded is exercised by the testcase already.  I indeed
have no good way to test actual folding besides an RTL testcase
(and I didn't add one for GIMPLE).

But as said elsehwere I don't see the RTL constant folding code
as important with regard to floats, but of course we have to fix it up.

The patch as-is fixes the reported testcase on x86_64, a target
eventually not implementing float but only unsigned_float might be
still broken.  I can put the same code in the unsigned_float code
but I have no way of exercising it.

Anyway, it feels like I spent too much time on this already for what
was supposed to be low-hanging fruit ;)

Richard.

Reply via email to