riscv-isa-manual
riscv-isa-manual copied to clipboard
NaN input handling in vfmerge, vfmv, vfslide1up, and vfslide1down
Hi,
For these floating point instructions (non-arithmetic type), do we check for input NaN-Boxing? Also, let's say if the scalar operand passes NaN-Boxing but it's a non-canonicalized NaN, do we convert that to canonical NaN before inserting that into the destination vector registers?
thanks, Liang-Kai
My understanding is: "Yes; No", based on the following text:
For floating-point operations, the scalar can be taken from a scalar f register. If FLEN > SEW, the value in the f registers is checked for a valid NaN-boxed value, in which case the least-significant SEW bits of the f register are used, else the canonical NaN value is used. Vector instructions where any floating-point vector operand’s EEW is not a supported floating-point type width (which includes when FLEN < SEW) are reserved.
https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#101-vector-arithmetic-instruction-encoding
Your term "non-arithmetic type" suggests to me that your question is more about the scope of this constraint, rather than its existence. I note that the instructions you consider to be "non-arithmetic type" live in the encoding space, defined at the beginning of Section 10, alongside other instructions that I think everyone would agree to be "arithmetic". This is what motivates my understanding of the spec.
So Yes for input NaN Box checking, but No for canonicalize the NaN after it passes the input NaN Box check. This is a bit interesting.
Generally, I would assume for data-move instruction, we don't want to change the value in any way even if it's failing NaN Box check. This can allow people to easily move the lower bits of, let's say, F64 number, to vector register so that they can do bit-level operations on mantissa without worrying about loss of the info.
But let's say we do want to apply the rule specified in the spec, I would think it needs to be consistent as the rule actually implies modification of the data. As a result, I would think applying NaN canonicalization on the result AFTER passing NaN box check make more sense. As an example, let's say SEW = 32, and someone puts 64'hffff_ff0f_ffff_ffff vs 64'hffff_ffff_ff80_ffff as input (and both are quiet NaN in F64), they would expect output to be canonical NaN in F32 (i.e. 32'h7fc0_0000), instead of one is 32'h7fc0_0000 (quite NaN) and the other is 32'hff80_ffff (Signaling NaN). By the way, I am only talking about data-move instruction here.
Perhaps someone may have asked previously and pardon me for the repeated question, why do we choose to do it this way?
This can allow people to easily move the lower bits of, let's say, F64 number, to vector register so that they can do bit-level operations on mantissa without worrying about loss of the info.
So, the use-case is to do vector arithmetic with the least-significant 32 bits of the (53-bit) significand of an FP64 scalar? I am quite curious to learn more about your application.
As a workaround, on RV64, I would suggest moving the FP64 value to an X-register: the .vx
instructions won't have the undesirable NaN-boxing behavior.
I'll let others explain the rationale for the current design.
Hi Nick,
Sorry I should use my words more carefully. I don't know such a use case myself, but I can imagine if someone who wants to extract bits from the lower bits of the significand to do "something", this will allow them to do just that. Of course, the value is probably extremely low.
Perhaps I should say I am more interested in understanding why we come to the conclusion of only applying NaN Box checks for data-move instructions and leave the bits unmodified after the NaN check (i.e. the second part of my question).
thanks, Liang-Kai
On Tue, May 2, 2023 at 8:50 PM Nick Knight @.***> wrote:
This can allow people to easily move the lower bits of, let's say, F64 number, to vector register so that they can do bit-level operations on mantissa without worrying about loss of the info.
So, the use-case is to do vector arithmetic with the least-significant 32 bits of the (53-bit) significand of an FP64 scalar? I am quite curious to learn more about your application.
As a workaround, on RV64, I would suggest moving the FP64 value to an X-register: the .vx instructions won't have the undesirable NaN-boxing behavior.
I'll let others explain the rationale for the current design.
— Reply to this email directly, view it on GitHub https://github.com/riscv/riscv-isa-manual/issues/1030#issuecomment-1532359059, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGWBFSU7EMYBPBVYJYIWI7TXEG2WHANCNFSM6AAAAAAXTWNV6I . You are receiving this because you authored the thread.Message ID: @.***>
--
thanks, Liang-Kai
I feel like it might be interesting to post a link to this issue in the vector-spec (https://github.com/riscv/riscv-v-spec/issues) as this seems to apply mostly to vectors (although NaN boxing is described in the main spec). This also applies to https://github.com/riscv/riscv-isa-manual/issues/1031.
It may help "vector people" monitoring mostly the vector spec to be aware of both these discussions.