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 [email protected]
