Open wahbahdoo opened 10 years ago
I think it's OK to leave it up to the implementation on whether to canonicalize a NaN value when extracting it from a float32 lane in a float32x4 object into a regular JS Number. In the example above this is happening for the 'n.x' in SIMD.float32x4.withX(n, n.x). Luke mentioned that it's OK, according to the spec, to have the JS engine choose to canonicalize, or not, when accessing a regular element in a Float32Array. Accessing a lane in a float32x4 object should follow the same rule.
BTW: Here's the wording from the spec:
4 Handling of Not-a-Number (NaN) Values
When the not-a-number (NaN) value is stored into a Float32Array or Float64Array, or into a DataView using the setFloat32 or setFloat64 methods, the bit pattern written into the underlying ArrayBuffer is not specified, but shall be one of the IEEE 754 bit patterns that represent NaN [IEEE-754].
When a bit pattern representing an IEEE 754 NaN is loaded from a Float32Array or Float64Array, or from a DataView using the getFloat32 or getFloat64 methods, the language binding (for example, ECMAScript) may use an alternative bit pattern to represent the NaN value.
The Web IDL [WEBIDL] and ECMA-262 [ECMA-262] specifications govern all other handling of NaN values, in particular the conversion to 0 when converting NaN to an integer value.
Yes, our (Firefox) current implementation canonicalizes NaNs at the point when a scalar is extracted from a SIMD value or when a scalar is loaded from a typed array. I don't think we require any spec changes here.
This issue is actually causing two tests in the "float32x4 int32x4 bit conversion" test to fail on SpiderMonkey. Currently, bitcasting from int32x4 to float32x4 and back to int32x4 is not a value-preserving sequence, beause the polyfill implements conversion to float32x4 via a typed array load, which does NaN canonicalization. I sent a pull request with a7a5c9a4e87ebebef792dc1e917dfc113e397805 to temporarily disable these tests for now.
We may want to add language to the SIMD.js spec saying that a bitcast to float32x4 or float64x2 when the value is a NaN bit pattern may be translated to a different NaN bit pattern.
The NaN canonicalization probably is what causes this issue too: https://github.com/kripken/emscripten/issues/2840
The SIMD spec, like the TypedArray spec, is careful not to require NaN canonicalization and to allow even canonicalizing implementations to store whatever bitpattern they want in a SIMD vector.
int32x4 bitcasted into a NaN float32x4 may pose semantics issues in runtimes that canonicalize NaNs. for example,
See https://github.com/johnmccutchan/ecmascript_simd/pull/36 and https://bugzilla.mozilla.org/show_bug.cgi?id=945382 for more details.