On 10/20/2022 10:43 AM, Andrew Haley wrote:
On Wed, 12 Oct 2022 17:00:15 GMT, Andrew Haley <a...@openjdk.org> wrote:

A bug in GCC causes shared libraries linked with -ffast-math to disable 
denormal arithmetic. This breaks Java's floating-point semantics.

The bug is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55522

One solution is to save and restore the floating-point control word around 
System.loadLibrary(). This isn't perfect, because some shared library might 
load another shared library at runtime, but it's a lot better than what we do 
now.

However, this fix is not complete. `dlopen()` is called from many places in the 
JDK. I guess the best thing to do is find and wrap them all. I'd like to hear 
people's opinions.
Andrew Haley has updated the pull request incrementally with one additional 
commit since the last revision:

   8295159: DSO created with -ffast-math breaks Java floating-point arithmetic
So here's a thought:

Reading and writing floating-point control flags can be expensive because they're 
serializing operations. However, we can discover whether the processor has been put into 
an "odd" rounding mode with just a few floating-point instructions, so we can 
do:


if (epsilon + epsilon == 0) {
       rtn = fesetenv(&default_fenv)
     }

Assuming the rounding mode could be one of the four classic rounding modes (to nearest even, to +infinity, to -infinity, to zero), two calculations are needed to determine if the mode is set to nearest even, as required by the JVM.

Candidate calculations are

1.0 + ROUND_THRESH == 1.0
-1.0 - ROUND_THRESH == -1.0

with the decoding

false false    => to nearest
false true    => to positive infinity
true false    => to negative infinity
true true     => to zero

For double, the double rounding threshold is 2^–53 + 2^–105 ≈ 1.1102230246251568e –16. An analogous constant can be derived for float, if desired

HTH,

-Joe

Reply via email to