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