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

Reply via email to