I am wondering whether there are any uses of Wasm that depend on NaN value canonicalization.
For some time I thought that our NaN semantics are identical to ECMAScript, but it looks like the latter (with some minor change to formatting, emphasis mine) does not distinguish between NaN bit patterns:
The Number type has exactly 18,437,736,874,454,810,627 values, representing the double-precision 64-bit format IEEE 754-2019 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9,007,199,254,740,990 distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special NaN value. (Note that the NaN value is produced by the program expression NaN.) In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-defined; to ECMAScript code, all NaN values are indistinguishable from each other.
while in Wasm a non-canonical NaN cannot be returned from operation consuming a canonical NaN:
When the result of a floating-point operator other than
fabs,fneg, orfcopysignis a NaN, then its sign is non-deterministic and the payload is computed as follows:
If the payload of all NaN inputs to the operator is canonical (including the case that there are no NaN inputs), then the payload of the output is canonical as well.
Otherwise the payload is picked non-deterministically among all arithmetic NaNs; that is, its most significant bit is and all others are unspecified.
This is much stricter property, and it comes with a cost for operations that might otherwise change NaN bits (fmin and fmax on x86 for example). However this distinction is completely ignored by most programming languages, which on the Web means Wasm code has to perform a somewhat costly conversion the rest of the browser is completely oblivious to. Also, for canonical/non-canonical distinction to be practically useful, non-canonical NaNs need to be produced and consumed as a form of metadata, however spec does not mandate their values are preserved, which makes the distinction at least partially moot.
What are the use cases that practically depend on this behavior? It is of course possible to construct a test that would depend on exact bit pattern, but what language/library does use that in practice (i.e. where the distinction is not 'implementation defined' or 'undefined')?