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 gcc/ * config/riscv/riscv.md (smin<mode>3): Rename pattern to... (fmin<mode>3): ... this. (smax<mode>3): Likewise... (fmax<mode>3): ... this. --- Hi, It's not clear to me how it's been missed or whether there is anything I might be actually missing. It looks to me like a clear oversight however. And in any case this change has passed full GCC regression testing (except for the D frontend, which has stopped being built recently due to a defect in Debian I haven't yet got to getting fixed) with the `riscv64-linux-gnu' target using the HiFive Unmatched (U74 CPU) target board, so it seems to be doing the right thing. Timing might a bit unfortunate for this submission and given that it is not a regression fix I guess this is GCC 13 material. Please let me know otherwise. In any case OK to apply (when the time comes)? Maciej --- gcc/config/riscv/riscv.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) gcc-riscv-fmin-fmax.diff Index: gcc/gcc/config/riscv/riscv.md =================================================================== --- gcc.orig/gcc/config/riscv/riscv.md +++ gcc/gcc/config/riscv/riscv.md @@ -1214,7 +1214,7 @@ ;; ;; .................... -(define_insn "smin<mode>3" +(define_insn "fmin<mode>3" [(set (match_operand:ANYF 0 "register_operand" "=f") (smin:ANYF (match_operand:ANYF 1 "register_operand" " f") (match_operand:ANYF 2 "register_operand" " f")))] @@ -1223,7 +1223,7 @@ [(set_attr "type" "fmove") (set_attr "mode" "<UNITMODE>")]) -(define_insn "smax<mode>3" +(define_insn "fmax<mode>3" [(set (match_operand:ANYF 0 "register_operand" "=f") (smax:ANYF (match_operand:ANYF 1 "register_operand" " f") (match_operand:ANYF 2 "register_operand" " f")))]