From patchwork Tue Feb 1 10:48:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 50616 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 144703857C64 for ; Tue, 1 Feb 2022 10:49:18 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by sourceware.org (Postfix) with ESMTPS id DDF8C3858C2D for ; Tue, 1 Feb 2022 10:49:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org DDF8C3858C2D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-lf1-x12e.google.com with SMTP id k13so631002lfg.9 for ; Tue, 01 Feb 2022 02:49:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:cc:subject:message-id:user-agent:mime-version; bh=k6LU/wn0CcsB2N+kfIuUXmRO2FvzX86jlfW8UKPaHK0=; b=ZhaCIBwtaSQf2392D1RF7q+cAp06zawRPHn7dRkhdHOEC4r0lQ4nksJQoegCc7UGSC ZqcmVGJdlDX5Z9GMF4eVPF8EA1PEO5TH+FO9RCEf/c8JQ4AQ3VRdTxrOO/imhOcYfAMn xSu9F7e5LzrgJOcC+DJNBTdRs8GoEk0xlZG+x93t1ufoapdY5dPx9t9JtIzZTUbNKIXS MgoGMgSP3wSItnB8N2nRB3A58xBC+Y65FXkLQmFbQhTBIMHJKY5C0zgqClQM3A/PIRZl MAWwlkOutEBk5rg5+K1jvA8McNUxFIcTO1Ox73AWUe2Fs0fVPHIToFcgvff+2JdgT/wb 6trw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:user-agent :mime-version; bh=k6LU/wn0CcsB2N+kfIuUXmRO2FvzX86jlfW8UKPaHK0=; b=QEvBFqnlJLnO+MS3I6ed72YpMoB27IQM7h3xZBPEfDQVtW2kcOw4JpfgbtnwUeXA/M 67NVacAX8FT+D+DJLFe3EjjR755jIpZM9ozEJeLz6oqTIUW+r7iEgOZc5gKgwGJBWc0U 0WjcL70SoiqJeZFz6WCSR+K+qAnduwkbvIXF3eQbg2vqqXSVJ5TQf316BXAhKDUEGBZt 2oJ3irfWG294QEdUEdDgt75ni6ShPID6uoq/yPzq1oLNbqEgqZb9f4W6otG8HCPMKKeN SKiGxSXiQRIxBU/w2VvU1yg1v8RzPD2nhiyCv8vxM01KM1UBnKnQgHIXZ9eysnO3pbDm ZdUQ== X-Gm-Message-State: AOAM530q1gHXS9SvLKY34NBANuSEG6Cs29K6Reogq9l8tmvQ+LCSxdW7 ESx6E8SbNISG8T29X0VgzK7kYreJlJgXRA== X-Google-Smtp-Source: ABdhPJw/euU+xKQGyBNMQcR385MgszGonhGyRvjezpcecutfqhLzX2cT+yV9a4l/88cZ/FV61LgZCA== X-Received: by 2002:a05:6512:1151:: with SMTP id m17mr18203667lfg.610.1643712539391; Tue, 01 Feb 2022 02:48:59 -0800 (PST) Received: from [192.168.219.3] ([78.8.192.131]) by smtp.gmail.com with ESMTPSA id z21sm4030823lfh.134.2022.02.01.02.48.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 01 Feb 2022 02:48:58 -0800 (PST) Date: Tue, 1 Feb 2022 10:48:54 +0000 (GMT) From: "Maciej W. Rozycki" To: gcc-patches@gcc.gnu.org Subject: [PATCH v3][GCC13] RISC-V: Provide `fmin'/`fmax' RTL patterns Message-ID: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, 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: , Cc: Kito Cheng , Joseph Myers , Andrew Waterman Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" 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. * testsuite/gcc.target/riscv/fmax-snan.c: New test. * testsuite/gcc.target/riscv/fmax.c: New test. * testsuite/gcc.target/riscv/fmaxf-snan.c: New test. * testsuite/gcc.target/riscv/fmaxf.c: New test. * testsuite/gcc.target/riscv/fmin-snan.c: New test. * testsuite/gcc.target/riscv/fmin.c: New test. * testsuite/gcc.target/riscv/fminf-snan.c: New test. * testsuite/gcc.target/riscv/fminf.c: New test. * testsuite/gcc.target/riscv/smax-ieee.c: New test. * testsuite/gcc.target/riscv/smax.c: New test. * testsuite/gcc.target/riscv/smaxf-ieee.c: New test. * testsuite/gcc.target/riscv/smaxf.c: New test. * testsuite/gcc.target/riscv/smin-ieee.c: New test. * testsuite/gcc.target/riscv/smin.c: New test. * testsuite/gcc.target/riscv/sminf-ieee.c: New test. * testsuite/gcc.target/riscv/sminf.c: New test. --- Hi, I thought some test coverage would be good having in this area, so I have added test cases for the new `fmin'/`fmax' and the existing `smin'/`smax' patterns and in the course of making this improvement I have realised the latter oned do actually have to be always available, and that using UNSPEC operations will be more appropriate for the former ones, especially as the respective RTL expressions previously used have non-IEEE semantics: '(smin:M X Y)' '(smax:M X Y)' Represents the smaller (for 'smin') or larger (for 'smax') of X and Y, interpreted as signed values in mode M. When used with floating point, if both operands are zeros, or if either operand is 'NaN', then it is unspecified which of the two operands is returned as the result. The new test cases assume the update I have recently submitted to make use of the `gcc-dg-runtest' test driver will go ahead. They are trivial to update otherwise (`-O2' would I guess be best used then). I chose to further update the change description so as to refer to both ISA revisions and "F"/"D" extension versions unambiguously. This third version of the change has passed full GCC regression testing with the `riscv64-linux-gnu' target using the HiFive Unmatched (U74 CPU) target board. Any further questions or comments? Otherwise OK once GCC 13 has opened? Maciej 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" } } */