RFR: 8295159: DSO created with -ffast-math breaks Java floating-point arithmetic [v7]

Joseph D. Darcy joe.darcy at oracle.com
Thu Oct 20 20:05:52 UTC 2022


On 10/20/2022 10:43 AM, Andrew Haley wrote:
> On Wed, 12 Oct 2022 17:00:15 GMT, Andrew Haley <aph at 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




More information about the build-dev mailing list