Why is floor() only compiled to roundsd when using -funsafe-math-optimizations?
Joseph Myers
joseph@codesourcery.com
Wed Jan 28 19:15:00 GMT 2015
On Wed, 28 Jan 2015, Tobias Burnus wrote:
> And, looking at the handling in GCC itself (for i386), it is secured by
>
> if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
> && !flag_trapping_math)
>
> Thus, using -fno-trapping-math or -fno-signaling-nans is enough - no need for
> -funsafe-math-optimizations.
>
> But that doesn't quite answer the question, why the !flag_trapping_math is
> needed. At least testing shows that both the GCC version and glibc are
> signalling a SNaN (when trapping is enabled).
I suppose !flag_trapping_math might be about preserving "inexact"
exceptions.
Now, TS 18661-1:2014 says that floor must not raise "inexact", so as to
make it a correct binding for the IEEE 754-2008 operation
roundToIntegralTowardNegative. That operation does not raise any
exceptions other than for signaling NaN operands (the logic being that the
mathematical result - the floor of the floating-point argument - is always
exactly representable in the floating-point format, so there is never any
inexactness). C99 and C11 Annex F leave the raising of "inexact"
unspecified.
So for C99 and C11, given the unspecifiedness of "inexact" exceptions, the
flag_trapping_math test seems unnecessary. And the instruction does
signal "invalid" for sNaN operands, so you shouldn't need to test for
those either. For TS 18661-1, the correct instruction variant to use
would be the one that does not raise "inexact" (argument 9 not 1 for
rounding mode, I think) - while that might change exceptions relative to a
library function not following TS 18661-1, changing in the direction of
being correct seems a good thing.
Thus: I think the relevant GCC code should include ROUND_NO_EXC (= 8) in
the rounding mode argument when expanding calls to round / floor / ceil /
trunc functions to use instructions such as roundsd. But calls to rint
should *not* use ROUND_NO_EXC (calls to nearbyint *should* use it, but it
seems SSE4.1 expansion for nearbyint is currently missing from the x86
back end). And none of those need to test flag_trapping_math in the case
of expanding to these SSE4.1 instructions.
--
Joseph S. Myers
joseph@codesourcery.com
More information about the Gcc
mailing list