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")))]