RISC-V's canonical NaN

1,564 views
Skip to first unread message

Dan Gohman

unread,
Apr 7, 2016, 11:12:00 AM4/7/16
to RISC-V ISA Dev
NaN boxing is an important technique in the field of JITs and dynamic language implementations, wherein the significand field (except the "quiet NaN" bit) of a NaN is used as a "payload" to carry other types of data. It is common for NaN boxing implementations to assume that hardware-produced NaNs have all-zeros payloads [0], as this is the behavior of ARM, MIPS (in NaN2008 mode), Power, x86, and others. Any NaN with a non-zero payload is then assumed to be carrying meaningful information.

The RISC-V ISA Manual, version 2.0, section "NaN Generation and Propagation", says that its hardware-generated NaN values are all-ones. While it's possible to implement NaN boxing under this definition, it will require different code, so it'll often mean more work porting to RISC-V, and, typically, more platform-specific #ifdefs to maintain.

And for WebAssembly, it's particularly problematic. WebAssembly is a new portable virtual ISA being designed, and it wishes to support code that does NaN boxing. As a virtual ISA, it can't rely on #ifdef to let programs specialize for the underlying hardware. The current hardware consensus of all-zeros payloads makes it feasible for WebAssembly to support programs that do NaN boxing in a portable and efficient manner. However, RISC-V's use of all-ones could add significant complexity, inefficiency, or both.

Would it be feasible to change RISC-V's "canonical NaN' to use an all-zeros payload?

Of course, the "quiet NaN" bit should continue to follow the IEEE 754-2008 semantics. And the sign bit can be whatever the architecture wants, since it's typically not relevant to NaN boxing.

Thanks,

Dan

kr...@berkeley.edu

unread,
Apr 9, 2016, 4:02:35 PM4/9/16
to Dan Gohman, RISC-V ISA Dev

Hi Dan,

As we reported at the last workshop, we realized there were a bunch of
holes in the spec regarding NaNs. We reviewed these, and decided to
change canonical NaN encoding to be same as ARM/JVM model, i.e., with
zero payloads.

Krste
| --
| You received this message because you are subscribed to the Google
| Groups "RISC-V ISA Dev" group. To unsubscribe from this group and
| stop receiving emails from it, send an email to
| isa-dev+u...@groups.riscv.org. To post to this group, send
| email to isa...@groups.riscv.org. Visit this group at
| https://groups.google.com/a/groups.riscv.org/group/isa-dev/ . To
| view this discussion on the web visit https://groups.google.com/a/
| groups.riscv.org/d/msgid/isa-dev/
| c501a22d-b34e-46b4-933d-a909b52236ed%40groups.riscv.org.

Dan Gohman

unread,
Apr 19, 2016, 5:56:45 PM4/19/16
to kr...@berkeley.edu, RISC-V ISA Dev
Hi Krste,

That's great! That will definitely simplify NaN-boxing use cases.

Would you also be interested in making the floating-point conversion instructions propagate NaN payload bits in a manner consistent with x86, ARM, Power, and others? Currently the RISC-V spec says "If a NaN value is converted to a different floating-point type, the result is the canonical NaN of the new type". However, these other platforms have the behavior that the payload is propagated in a conversion, with zeros being added in the least significant bits for a widening conversion, or with the least significant bits being discarded in a narrowing conversion.

This would enable use cases where extra information is being stored in the most significant bits of a NaN payload, where it's desirable for this information to be retained across a type conversion. This is admittedly less common than the NaN boxing issue I previously mentioned, however overall, supporting this would eliminate a difference when porting code to RISC-V.

Thanks,

Dan

Krste Asanovic

unread,
Apr 19, 2016, 6:24:34 PM4/19/16
to Dan Gohman, RISC-V ISA Dev

We considered supporting payloads but frankly could not find any example of this being used portably in practice.

The whole concept does seem a little brittle to us, and there is a non-zero hardware cost to propagating NaN payloads for many FP operations.

We realize having payload propagation be optional makes it unlikely to be implemented, but we’d like to see some compelling portable use cases before mandating extra hardware on every RISC-V FPU implementation.

Here’s the latest version of this section from the very-soon-to-be-released updated manual,

Krste


7.3 NaN Generation and Propagation 

Except when otherwise stated, if the result of a floating-point operation is NaN, it is the canonical NaN. The canonical NaN has a positive sign and all significand bits clear except the MSB, a.k.a. the quiet bit. For single-precision floating-point, this corresponds to the pattern 0x7fc00000.

For FMIN and FMAX, if at least one input is a signaling NaN, or if both inputs are quiet NaNs, the result is the canonical NaN. If one operand is a quiet NaN and the other is not a NaN, the result is the non-NaN operand.

The sign-injection instructions (FSGNJ, FSGNJN, FSGNJX) do not canonicalize NaNs; they manipulate the underlying bit patterns directly.

We considered propagating NaN payloads, as is recommended by the standard, but this decision would have increased hardware cost. Moreover, since this feature is optional in the standard, it cannot be used in portable code.

Implementors are free to provide a NaN payload propagation scheme as a nonstandard exten- sion enabled by a nonstandard operating mode. However, the canonical NaN scheme described above must always be supported and should be the default mode.

 

Reply all
Reply to author
Forward
0 new messages