On Wed, 22 Feb 2023 05:21:48 GMT, Joe Darcy <da...@openjdk.org> wrote:

>> I'm also a bit concerned that we are rushing in to "fix" this. IIUC we have 
>> three mechanisms for implementing this functionality:
>> 
>> 1. The interpreted Java code
>> 2. The compiled non-intrinisc sharedRuntime code
>> 3. The compiler intrinsic that uses a hardware instruction.
>> 
>> Unless the hardware instructions for all relevant CPUs behave exactly the 
>> same, then I don't see how we can have parity of behaviour across these 
>> three mechanisms.
>> 
>> The observed behaviour may be surprising but it seems not to be a bug. And 
>> is this even a real concern - would real programs actually need to peek at 
>> the raw bits and so see the difference, or does it suffice to handle Nan's 
>> opaquely?
>
>> I'm also a bit concerned that we are rushing in to "fix" this. IIUC we have 
>> three mechanisms for implementing this functionality:
>> 
>>     1. The interpreted Java code
>> 
>>     2. The compiled non-intrinisc sharedRuntime code
>> 
>>     3. The compiler intrinsic that uses a hardware instruction.
>> 
>> 
>> Unless the hardware instructions for all relevant CPUs behave exactly the 
>> same, then I don't see how we can have parity of behaviour across these 
>> three mechanisms.
>> 
>> The observed behaviour may be surprising but it seems not to be a bug. And 
>> is this even a real concern - would real programs actually need to peek at 
>> the raw bits and so see the difference, or does it suffice to handle Nan's 
>> opaquely?
> 
> From the spec 
> (https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Float.html#float16ToFloat(short))
> 
> "Returns the float value closest to the numerical value of the argument, a 
> floating-point binary16 value encoded in a short. The conversion is exact; 
> all binary16 values can be exactly represented in float. Special cases:
> 
>     If the argument is zero, the result is a zero with the same sign as the 
> argument.
>     If the argument is infinite, the result is an infinity with the same sign 
> as the argument.
>     If the argument is a NaN, the result is a NaN. "
> 
> If the float argument is a NaN, you are supposed to get a float16 NaN as a 
> result -- that is all the specification requires. However, the implementation 
> makes stronger guarantees to try to preserve some non-zero NaN significand 
> bits if they are set.
> 
> "NaN boxing" is a technique used to put extra information into the 
> significand bits a NaN and pass the around. It is consistent with the 
> intended use of the feature by IEEE 754 and used in various language 
> runtimes: e.g.,
> 
> https://piotrduperas.com/posts/nan-boxing
> https://leonardschuetz.ch/blog/nan-boxing/ 
> https://anniecherkaev.com/the-secret-life-of-nan
> 
> The Java specs are careful to avoid mentioning quiet vs signaling NaNs in 
> general discussion.
> 
> That said, I think it is reasonable on a given JVM invocation if 
> Float.floatToFloat16(f) gave the same result for input f regardless of in 
> what context it was called.

We don't know that all HW will produce the same NaN "payload", right?  Instead, 
we might need interpreter intrinsics.  I assume that is how the trig functions 
are handled that @jddarcy mentioned.

-------------

PR: https://git.openjdk.org/jdk/pull/12704

Reply via email to