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