On Thu, 20 Jan 2022, Maciej W. Rozycki wrote:

> RISC-V FMIN and FMAX machine instructions are IEEE-754-conformant[1]:
> 
> "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."
> 
> as required by our `fminM3' and `fmaxM3' standard RTL patterns.
> 
> However we only define `sminM3' and `smaxM3' standard RTL patterns to 
> produce the FMIN and FMAX machine instructions, which in turn causes the 
> `__builtin_fmin' and `__builtin_fmax' family of intrinsics to emit the 
> corresponding libcalls rather than the relevant machine instructions.
> 
> Rename the `smin<mode>3' and `smax<mode>3' patterns to `fmin<mode>3' and 
> `fmax<mode>3' respectively then, removing the need to use libcalls for 
> IEEE 754 semantics with the minimum and maximum operations.
> 
> [1] "The RISC-V Instruction Set Manual, Volume I: User-Level ISA",
>     Document Version 2.2, May 7, 2017, Section 8.3 "NaN Generation and 
>     Propagation", p. 48

That's an old version of the instruction set, and an old version of IEEE 
754.

The C functions fmin and fmax correspond to the IEEE 754-2008 operations 
minNum and maxNum, which operate as described, and the RISC-V 'F' and 'D' 
extensions *before* version 2.2 of those extensions also corresponded to 
minNum and maxNum.

IEEE 754-2019 removes minNum and maxNum because they are non-associative 
in the presence of signaling NaNs, replacing them with new operations 
minimum, minimumNumber, maximum, maximumNumber.  C23 defines new functions 
fminimum, fminimum_num, fmaximum, fmaximum_num corresponding to those new 
operations, leaving fmin and fmax unchanged.  And the RISC-V 'F' and 'D' 
extensions version 2.2 change the FMIN and FMAX instructions to correspond 
to minimumNumber and maximumNumber instead of minNum and maxNum.

So, if generating code that might be run on processors implementing 
versions of 'F' and 'D' older than 2.2, it's not safe to generate FMAX and 
FMIN instructions for any of those standard C library functions when 
signaling NaN operands are a possibility (i.e. flag_signaling_nans is 
set), because code built for older versions might run on newer versions 
with changed instruction semantics.  If generating code that requires 
version 2.2 or later of 'F' and 'D' (and I don't know if GCC actually 
supports generating code for older versions), it's OK to generate those 
instructions as part of expanding calls to the C23 functions fminimum_num 
and fmaximum_num - but not as part of expanding calls to fmin and fmax 
(unless !flag_signaling_nans, in which case the differences between those 
functions aren't relevant).  And GCC currently doesn't have built-in 
functions for fminimum_num and fmaximum_num, and I don't think it has insn 
patterns corresponding to those functions either.

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to