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