On Thu, Oct 01, 2015 at 05:43:15PM +0200, Michael Matz wrote:
> Hi,
>
> On Thu, 1 Oct 2015, James Greenhalgh wrote:
>
> > > > x * copysign (1.0, y)
> > > >
> > > > x ^ (y & (1 << sign_bit_position))
> > >
> > > Also I think this can only be done for finite and non trapping types.
> >
> > That may be well true, I swithered either way and went for no checks,
> > but I'd happily go back on that and wrap this in something suitable
> > restrictive if I need to.
>
> I don't think that's necessary. copysign (1.0, y) is always 1.0 or -1.0,
> even with y being a NaN or inf. Additionally copysign is allowed to not
> signal even if y is a sNaN. That leaves only the form of x to doubt. If
> x is inf all is well (multiplying by +-1.0 is defined and both sequences
> get the same result), if x is NaN the result must be a NaN, and it is in
> both cases. The catch is that strictly speaking (NaN * -1.0) needs to
> deliver NaN, not -NaN (operations involving quiet NaNs need to provide
> one of the input NaNs as result), and here both are not equivalent. OTOH
> the sign of NaNs isn't specified, so I think we could reasonably decide to
> not care about this case (it would have to be checked if the hardware
> multiplication even follows that rule, otherwise it's moot anyway).
But if x is a sNaN, then the multiplication will throw an exception, while
the transformed operation will not. So perhaps it should be guarded by
!HONOR_SNANS (TYPE_MODE (type))
? And sure, somebody should look at why this isn't done in SSE.
Jakub