On 26 January 2015 at 23:50, Fredrik Tolf <[email protected]> wrote:
> Consider the following small program:
[...]
> When compiling this with a -march that supports the roundsd instruction, the
> floor() call seems to only be compiled to such an instruction if
> -funsafe-math-optimizations is specified.
>
> Why is this? I notice the glibc's floor() implementation (for SSE4.1-enabled
> processors) consists of only this instruction, so barring a bug in glibc,
> that would seem to imply to me the roundsd is IEEE-compliant and safe. Why
> does GCC consider it unsafe?
Partial answer.
I first want to point to POSIX, which has:
"floor, floorf, floorl - floor function" [...]
"An application wishing to check for error situations should set errno to
zero and call feclearexcept(FE_ALL_EXCEPT) before calling these functions.
On return, if errno is non-zero or fetestexcept(FE_INVALID |
FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) is non-zero, an error has occurred."
No one seems to care about the "errno" handling (and prefers to use
the trapping information directly), thus, I wouldn't be surprised if most libc
do not set errno.
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).
Tobias