From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com [IPv6:2a00:1450:4864:20::62c]) by sourceware.org (Postfix) with ESMTPS id 392953836010 for ; Tue, 10 May 2022 15:48:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 392953836010 Received: by mail-ej1-x62c.google.com with SMTP id ks9so27399053ejb.2 for ; Tue, 10 May 2022 08:48:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=jbr8KFA6vjGaITkYD/TdpFTwt2XRcQUrLZUjuT4cNg8=; b=ElPAV+DUphHlaUh1sHoKP3MYSotd9yOTwaaLwDYIBZ/ATDpUzghSM2ivba+Xhpr8wh KAhaPgIdEFsGCVsqmu50IG3ec3tnoer+14xLaiN95uqq0ae9F6qLxSnxiV9v9j5pMxDG sfLVj54PALr6u9vCblXkmN1BrQQY6y0JjkMvp0GfIJ7QSOxKleoI/SivvGgWsR6KQc8O 7/4KA/L5VMTesJ4XpRv0SQzPH9icx13YGZ0k23vo/Nnn8R7UAZGiyVbOlJaLpfjEekQx 9MrAsu2eATl1n70qxizj/D4YdWoM8BlV8z1R63o7l/Qaq9B6jzfBCPw/TdYptAGLJozE s36w== X-Gm-Message-State: AOAM530ZIbdFr0zLdI+txLf1hEboMYoWJC6hGJnufNDReYkYAq64Xzl1 r1kQAcR0bZd07HCl/m+3et75APUqpDZNJTrmVodulmhV X-Google-Smtp-Source: ABdhPJygvWIK4w5rJYzmFdKA0g4XwoI75NTybDkIBBxj7mghSrTKqRUFKe/X8oWO2kd9TAsvc/SAWCCjPFQLkgkE72M= X-Received: by 2002:a17:906:9f0c:b0:6f5:bed:d0a8 with SMTP id fy12-20020a1709069f0c00b006f50bedd0a8mr19984325ejc.94.1652197724983; Tue, 10 May 2022 08:48:44 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Kito Cheng Date: Tue, 10 May 2022 23:48:33 +0800 Message-ID: Subject: Re: [RESEND][committed v4] RISC-V: Provide `fmin'/`fmax' RTL patterns To: "Maciej W. Rozycki" Cc: Jim Wilson , GCC Patches , Joseph Myers , Andrew Waterman Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 May 2022 15:48:50 -0000 Thanks Maciej! On Tue, May 10, 2022 at 10:05 PM Maciej W. Rozycki wrote: > > As at r2.2 of the RISC-V ISA specification[1] (equivalent to version 2.0 > of the "F" and "D" standard architecture extensions for single-precision > and double-precision floating-point respectively) the FMIN and FMAX > machine instructions fully match our requirement for the `fminM3' and > `fmaxM3' standard RTL patterns: > > "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." > > suitably for the IEEE 754-2008 `minNum' and `maxNum' operations. > > 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. > This is according to earlier revisions of the RISC-V ISA specification, > which we however do not support anymore, as from commit 4b81528241ca > ("RISC-V: Support version controling for ISA standard extensions"). > > As from r20190608 of the RISC-V ISA specification (equivalent to version > 2.2 of the "F" and "D" standard ISA extensions for single-precision and > double-precision floating-point respectively) the definition of the FMIN > and FMAX machine instructions has been updated[2]: > > "Defined the signed-zero behavior of FMIN.fmt and FMAX.fmt, and changed > their behavior on signaling-NaN inputs to conform to the minimumNumber > and maximumNumber operations in the proposed IEEE 754-201x > specification." > > and specifically[3]: > > "Floating-point minimum-number and maximum-number instructions FMIN.S > and FMAX.S write, respectively, the smaller or larger of rs1 and rs2 to > rd. For the purposes of these instructions only, the value -0.0 is > considered to be less than the value +0.0. If both inputs are NaNs, the > result is the canonical NaN. If only one operand is a NaN, the result > is the non-NaN operand. Signaling NaN inputs set the invalid operation > exception flag, even when the result is not NaN." > > Consequently for forwards compatibility with r20190608+ hardware we > cannot use the FMIN and FMAX machine instructions unconditionally even > where the ISA level of r2.2 has been specified with the `-misa-spec=2.2' > option where operation would be different between ISA revisions, that > is the handling of signaling NaN inputs. > > Therefore provide new `fmin3' and `fmax3' patterns removing > the need to emit libcalls with the `__builtin_fmin' and `__builtin_fmax' > family of intrinsics, however limit them to where `-fno-signaling-nans' > is in effect, deferring to other code generation strategies otherwise as > applicable. Use newly-defined UNSPECs as the operation codes so that > the patterns are only ever used if referred to by their names, as there > is no RTL expression defined for the IEEE 754-2008 `minNum' and `maxNum' > operations. > > References: > > [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 > > [1] "The RISC-V Instruction Set Manual, Volume I: Unprivileged ISA", > Document Version 20190608-Base-Ratified, June 8, 2019, "Preface", > p. ii > > [2] same, Section 11.6 "Single-Precision Floating-Point Computational > Instructions", p. 66 > > gcc/ > * config/riscv/riscv.md (UNSPEC_FMIN, UNSPEC_FMAX): New > constants. > (fmin3, fmax3): New insns. > > gcc/testsuite/ > * gcc.target/riscv/fmax-snan.c: New test. > * gcc.target/riscv/fmax.c: New test. > * gcc.target/riscv/fmaxf-snan.c: New test. > * gcc.target/riscv/fmaxf.c: New test. > * gcc.target/riscv/fmin-snan.c: New test. > * gcc.target/riscv/fmin.c: New test. > * gcc.target/riscv/fminf-snan.c: New test. > * gcc.target/riscv/fminf.c: New test. > * gcc.target/riscv/smax-ieee.c: New test. > * gcc.target/riscv/smax.c: New test. > * gcc.target/riscv/smaxf-ieee.c: New test. > * gcc.target/riscv/smaxf.c: New test. > * gcc.target/riscv/smin-ieee.c: New test. > * gcc.target/riscv/smin.c: New test. > * gcc.target/riscv/sminf-ieee.c: New test. > * gcc.target/riscv/sminf.c: New test. > --- > On Mon, 28 Feb 2022, Jim Wilson wrote: > > > On Tue, Feb 8, 2022 at 4:35 AM Maciej W. Rozycki wrote: > > > > > gcc/ > > > * config/riscv/riscv.md (UNSPEC_FMIN, UNSPEC_FMAX): New > > > constants. > > > (fmin3, fmax3): New insns. > > > ... > > > > > > I tried testing on some of the hardware I have. Both the HiFive Unleashed > > (2018) and HiFive Unmatched (2021) implement the current definition of > > fmin/fmax. But the Allwinner Nezha (2021) implements the previous > > definition of fmin/fmax. SiFive was involved with the fmin/fmax change, so > > it isn't surprising that they implemented the new semantics before other > > companies. The Nezha board with the T-Head C906 is a popular one, so we do > > need to continue to support the 2017 spec, which your patch does with the > > HONORS_SNAN checks. I agree that we don't need to worry about spec > > versions older than that. > > > > This looks OK to me. > > > > I've got builds running in parallel on the Unleashed and Unmatched to test > > but that will take a couple of days and I don't expect any problems since > > you already tested it. I could do a build on the Nezha if I had to, but > > that would take at least a week as it is a much slower board and I'd rather > > not do that unless I have to. This is hardware implementing the older spec > > that you probably haven't tested though. > > Correct, I have only verified this change with an Unmatched system. > > Since Stage 1 is now back I have rerun regression testing with the change > included, both without and with `-fsignaling-nans' given. There were no > changes in results between the runs except for intermittent failures with > gfortran.dg/ISO_Fortran_binding_17.f90 at various optimisation levels, > clearly unrelated as this test does some DWARF information inspection. > > I have committed this change now, thank you for your review. > > Maciej > > Changes from v3: > > - Quote `\' characters in `scan-assembler' for literal `.' in regexp. > > - Mechanically update ChangeLog to have its entries separately for the > testsuite. > > Changes from v2: > > - Use UNSPECs for the `fmin'/`fmax' patterns, so that they cannot be > matched by the RTL expression. > > - Revert the `HONOR_SNANS (mode)' restriction for the `smin'/`smax' > patterns; it was wrong, because HONOR_SNANS implies HONOR_NANS, and that > is not true for `-ffinite-math-only' where `smin'/`smax' still have to > work. > > - Add test cases. > > - Further clarify ISA/extension revisions/versions. > > Changes from v1: > > - Adjust heading from "RISC-V: Replace `smin'/`smax' RTL patterns with > `fmin'/`fmax'". > > - Do not remove `smin'/`smax' patterns; instead make them available if > `HONOR_SNANS (mode)'. > > - Make `fmin'/`fmax' patterns available if `!HONOR_SNANS (mode)' > only. > > - Update description accordingly; refer r2.2 and r20190608 ISA specs. > --- > gcc/config/riscv/riscv.md | 22 ++++++++++++++++++++++ > gcc/testsuite/gcc.target/riscv/fmax-snan.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/fmax.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/fmaxf-snan.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/fmaxf.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/fmin-snan.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/fmin.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/fminf-snan.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/fminf.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/smax-ieee.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/smax.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/smaxf-ieee.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/smaxf.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/smin-ieee.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/smin.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/sminf-ieee.c | 12 ++++++++++++ > gcc/testsuite/gcc.target/riscv/sminf.c | 12 ++++++++++++ > 17 files changed, 214 insertions(+) > > 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 > @@ -42,6 +42,8 @@ > UNSPEC_COPYSIGN > UNSPEC_LRINT > UNSPEC_LROUND > + UNSPEC_FMIN > + UNSPEC_FMAX > > ;; Stack tie > UNSPEC_TIE > @@ -1216,6 +1218,26 @@ > ;; > ;; .................... > > +(define_insn "fmin3" > + [(set (match_operand:ANYF 0 "register_operand" "=f") > + (unspec:ANYF [(use (match_operand:ANYF 1 "register_operand" " f")) > + (use (match_operand:ANYF 2 "register_operand" " f"))] > + UNSPEC_FMIN))] > + "TARGET_HARD_FLOAT && !HONOR_SNANS (mode)" > + "fmin.\t%0,%1,%2" > + [(set_attr "type" "fmove") > + (set_attr "mode" "")]) > + > +(define_insn "fmax3" > + [(set (match_operand:ANYF 0 "register_operand" "=f") > + (unspec:ANYF [(use (match_operand:ANYF 1 "register_operand" " f")) > + (use (match_operand:ANYF 2 "register_operand" " f"))] > + UNSPEC_FMAX))] > + "TARGET_HARD_FLOAT && !HONOR_SNANS (mode)" > + "fmax.\t%0,%1,%2" > + [(set_attr "type" "fmove") > + (set_attr "mode" "")]) > + > (define_insn "smin3" > [(set (match_operand:ANYF 0 "register_operand" "=f") > (smin:ANYF (match_operand:ANYF 1 "register_operand" " f") > Index: gcc/gcc/testsuite/gcc.target/riscv/fmax-snan.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fmax-snan.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fsignaling-nans -dp" } */ > + > +double > +fmax (double x, double y) > +{ > + return __builtin_fmax (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\tfmax\\.d\t" } } */ > +/* { dg-final { scan-assembler-not "\tfge\\.d\t" } } */ > +/* { dg-final { scan-assembler "\t(call|tail)\tfmax\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/fmax.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fmax.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fno-signaling-nans -dp" } */ > + > +double > +fmax (double x, double y) > +{ > + return __builtin_fmax (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfmax\t" } } */ > +/* { dg-final { scan-assembler-not "\tfge\\.d\t" } } */ > +/* { dg-final { scan-assembler "\tfmax\\.d\t\[^\n\]* fmaxdf3\n" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/fmaxf-snan.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fmaxf-snan.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fsignaling-nans -dp" } */ > + > +float > +fmaxf (float x, float y) > +{ > + return __builtin_fmaxf (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\tfmax\\.s\t" } } */ > +/* { dg-final { scan-assembler-not "\tfge\\.s\t" } } */ > +/* { dg-final { scan-assembler "\t(call|tail)\tfmaxf\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/fmaxf.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fmaxf.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fno-signaling-nans -dp" } */ > + > +float > +fmaxf (float x, float y) > +{ > + return __builtin_fmaxf (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfmaxf\t" } } */ > +/* { dg-final { scan-assembler-not "\tfge\\.s\t" } } */ > +/* { dg-final { scan-assembler "\tfmax\\.s\t\[^\n\]* fmaxsf3\n" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/fmin-snan.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fmin-snan.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fsignaling-nans -dp" } */ > + > +double > +fmin (double x, double y) > +{ > + return __builtin_fmin (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\tfmin\\.d\t" } } */ > +/* { dg-final { scan-assembler-not "\tfle\\.d\t" } } */ > +/* { dg-final { scan-assembler "\t(call|tail)\tfmin\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/fmin.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fmin.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fno-signaling-nans -dp" } */ > + > +double > +fmin (double x, double y) > +{ > + return __builtin_fmin (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfmin\t" } } */ > +/* { dg-final { scan-assembler-not "\tfle\\.d\t" } } */ > +/* { dg-final { scan-assembler "\tfmin\\.d\t\[^\n\]* fmindf3\n" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/fminf-snan.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fminf-snan.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fsignaling-nans -dp" } */ > + > +float > +fminf (float x, float y) > +{ > + return __builtin_fminf (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\tfmin\\.s\t" } } */ > +/* { dg-final { scan-assembler-not "\tfle\\.s\t" } } */ > +/* { dg-final { scan-assembler "\t(call|tail)\tfminf\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/fminf.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/fminf.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fno-finite-math-only -fsigned-zeros -fno-signaling-nans -dp" } */ > + > +float > +fminf (float x, float y) > +{ > + return __builtin_fminf (x, y); > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfminf\t" } } */ > +/* { dg-final { scan-assembler-not "\tfle\\.s\t" } } */ > +/* { dg-final { scan-assembler "\tfmin\\.s\t\[^\n\]* fminsf3\n" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/smax-ieee.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/smax-ieee.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fsigned-zeros -dp" } */ > + > +double > +smax (double x, double y) > +{ > + return x >= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\t(call|tail)\tfmax\t" } } */ > +/* { dg-final { scan-assembler-not "\tfmax\\.d\t" } } */ > +/* { dg-final { scan-assembler "\tfge\\.d\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/smax.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/smax.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fno-signed-zeros -dp" } */ > + > +double > +smax (double x, double y) > +{ > + return x >= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfmax\t" } } */ > +/* { dg-final { scan-assembler-not "\tfge\\.d\t" } } */ > +/* { dg-final { scan-assembler "\tfmax\\.d\t\[^\n\]* smaxdf3\n" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/smaxf-ieee.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fsigned-zeros -dp" } */ > + > +float > +smaxf (float x, float y) > +{ > + return x >= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\t(call|tail)\tfmaxf\t" } } */ > +/* { dg-final { scan-assembler-not "\tfmax\\.s\t" } } */ > +/* { dg-final { scan-assembler "\tfge\\.s\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/smaxf.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/smaxf.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fno-signed-zeros -dp" } */ > + > +float > +smaxf (float x, float y) > +{ > + return x >= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfmaxf\t" } } */ > +/* { dg-final { scan-assembler-not "\tfge\\.s\t" } } */ > +/* { dg-final { scan-assembler "\tfmax\\.s\t\[^\n\]* smaxsf3\n" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/smin-ieee.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/smin-ieee.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fsigned-zeros -dp" } */ > + > +double > +smin (double x, double y) > +{ > + return x <= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\t(call|tail)\tfmin\t" } } */ > +/* { dg-final { scan-assembler-not "\tfmin\\.d\t" } } */ > +/* { dg-final { scan-assembler "\tfle\\.d\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/smin.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/smin.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fno-signed-zeros -dp" } */ > + > +double > +smin (double x, double y) > +{ > + return x <= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfmin\t" } } */ > +/* { dg-final { scan-assembler-not "\tfle\\.d\t" } } */ > +/* { dg-final { scan-assembler "\tfmin\\.d\t\[^\n\]* smindf3\n" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/sminf-ieee.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/sminf-ieee.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fsigned-zeros -dp" } */ > + > +float > +sminf (float x, float y) > +{ > + return x <= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\t(call|tail)\tfminf\t" } } */ > +/* { dg-final { scan-assembler-not "\tfmin\\.s\t" } } */ > +/* { dg-final { scan-assembler "\tfle\\.s\t" } } */ > Index: gcc/gcc/testsuite/gcc.target/riscv/sminf.c > =================================================================== > --- /dev/null > +++ gcc/gcc/testsuite/gcc.target/riscv/sminf.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* { dg-options "-ffinite-math-only -fno-signed-zeros -dp" } */ > + > +float > +sminf (float x, float y) > +{ > + return x <= y ? x : y; > +} > + > +/* { dg-final { scan-assembler-not "\ttail\tfminf\t" } } */ > +/* { dg-final { scan-assembler-not "\tfle\\.s\t" } } */ > +/* { dg-final { scan-assembler "\tfmin\\.s\t\[^\n\]* sminsf3\n" } } */