Date: Sat, 21 Nov 2015 20:37:24 +0000 From: bugzilla-noreply@freebsd.org To: freebsd-bugs@FreeBSD.org Subject: [Bug 204671] clang floating point wrong around Inf (i386) Message-ID: <bug-204671-8-kMVwFWIOER@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-204671-8@https.bugs.freebsd.org/bugzilla/> References: <bug-204671-8@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=204671 Jilles Tjoelker <jilles@FreeBSD.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jilles@FreeBSD.org --- Comment #2 from Jilles Tjoelker <jilles@FreeBSD.org> --- This is related to the strangeness that is the x87 FPU. Internally, the x87 performs calculations in extended precision. Even if the precision control is set to double precision, like FreeBSD and Windows do by default but Linux and Solaris do not, the x87 registers still have greater range than double precision. As a result, the addition 1e308 + 1e308 does not overflow, but produces a result of approximately 2e308 in an x87 register. When this result is stored to memory in double precision format, overflow or rounding will occur. What happens in t1.c is that the conversion from extended to double precision happens two times. The conversion for printing the bytes happens directly after the calculation and therefore uses the modified rounding mode. The conversion for printf happens during the inlined fesetround() call, after setting the x87 rounding mode and before calling a function __test_sse to check whether SSE is available. (After that, the value is stored and loaded again a few times.) Therefore, the conversion for printf uses an incorrect rounding mode. Global variables force the compiler to store values to memory more often and may therefore reduce x87 weirdnesses. Following the C standard, you would have to use #pragma STDC FENV_ACCESS on to make this work reliably. However, neither gcc nor clang support this pragma. They follow an ad hoc approach to floating point exceptions and modes. In gcc you can use -frounding-math to prevent some problematic optimizations but clang doesn't even support that. Clang has a bug about the pragma, https://llvm.org/bugs/show_bug.cgi?id=8100, which has been open for five years with various duplicates but no other significant action. You will generally have fewer problems with weirdly changing floating point results if you use SSE instead of the x87 FPU, assuming your CPUs are new enough. SSE performs calculations in the precision specified by the program (single or double), so it does not matter when or if a value is spilled to memory. As noted above, GCC and clang are still ignorant about the side effects with the floating point exceptions and modes, though. -- You are receiving this mail because: You are the assignee for the bug.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-204671-8-kMVwFWIOER>