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:18:13 UTC 2022


PS And additional expressions could be crashed to rule out 
flush-to-zero, treating all subnormals and zero, and other non-compliant 
modes of operation.

-Joe

On 10/20/2022 1:05 PM, Joseph D. Darcy wrote:
>
> 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