RISC-V: Add vector fmin/fmax expanders.
Checks
Commit Message
Hi,
this patch adds expanders for fmin and fmax and the associated
cond and reduc ones. As per RISC-V V spec 1.0 vfmin/vfmax are
IEEE 754-2008 compliant so that should be ok.
Regards
Robin
gcc/ChangeLog:
* config/riscv/autovec.md (<ieee_fmaxmin_op><mode>3): fmax/fmin
expanders.
(cond_<ieee_fmaxmin_op><mode>): Ditto.
(cond_len_<ieee_fmaxmin_op><mode>): Ditto.
(reduc_fmax_scal_<mode>): Ditto.
(reduc_fmin_scal_<mode>): Ditto.
* config/riscv/riscv-v.cc (needs_fp_rounding): Add fmin/fmax.
* config/riscv/vector-iterators.md (fmin): New UNSPEC.
(UNSPEC_VFMIN): Ditto.
* config/riscv/vector.md (@pred_<ieee_fmaxmin_op><mode>): Add
UNSPEC insn patterns.
(@pred_<ieee_fmaxmin_op><mode>_scalar): Ditto.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Remove
-ffast-math.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/binop/fmax-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c: New test.
---
gcc/config/riscv/autovec.md | 72 +++++++++++++++++++
gcc/config/riscv/riscv-v.cc | 2 +
gcc/config/riscv/vector-iterators.md | 8 +++
gcc/config/riscv/vector.md | 43 +++++++++++
.../riscv/rvv/autovec/binop/fmax-1.c | 24 +++++++
.../riscv/rvv/autovec/binop/fmax_run-1.c | 47 ++++++++++++
.../riscv/rvv/autovec/binop/fmax_zvfh-1.c | 23 ++++++
.../riscv/rvv/autovec/binop/fmax_zvfh_run-1.c | 48 +++++++++++++
.../riscv/rvv/autovec/binop/fmin-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_run-1.c | 5 ++
.../riscv/rvv/autovec/binop/fmin_zvfh-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_zvfh_run-1.c | 5 ++
.../riscv/rvv/autovec/cond/cond_fmax-1.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax-3.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-4.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-1.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-3.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-4.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c | 32 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c | 32 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c | 32 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c | 32 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-1.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-2.c | 32 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-3.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-4.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmin-1.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmin-3.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-4.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-1.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-2.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-3.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-4.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c | 10 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c | 10 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c | 10 +++
.../rvv/autovec/cond/cond_fmin_zvfh_run-1.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-2.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-3.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-4.c | 5 ++
.../riscv/rvv/autovec/reduc/reduc-10.c | 26 +++++++
.../riscv/rvv/autovec/reduc/reduc_run-10.c | 41 +++++++++++
.../rvv/autovec/reduc/reduc_run_zvfh-10.c | 41 +++++++++++
.../riscv/rvv/autovec/reduc/reduc_zvfh-10.c | 24 +++++++
48 files changed, 783 insertions(+), 25 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
Comments
On Mon, 30 Oct 2023, Robin Dapp wrote:
> Hi,
>
> this patch adds expanders for fmin and fmax and the associated
> cond and reduc ones. As per RISC-V V spec 1.0 vfmin/vfmax are
> IEEE 754-2008 compliant so that should be ok.
Aren't they actually the IEEE 754-2019 operations (with different
signaling NaN semantics; C functions such as fmaximum in C23), not the
IEEE 754-2008 operations (C functions such as fmax)? V spec 1.0 says "The
vector floating-point vfmin and vfmax instructions have the same behavior
as the corresponding scalar floating-point instructions in version 2.2 of
the RISC-V F/D/Q extension.". And version 2.2 of F/D/Q (which is *not*
version 2.2 of the instruction set, it's later than that) changed the
scalar instructions to be the IEEE 754-2019 operations (thus, the
!HONOR_SNANS checks in the back end).
> Aren't they actually the IEEE 754-2019 operations (with different
> signaling NaN semantics; C functions such as fmaximum in C23), not the
> IEEE 754-2008 operations (C functions such as fmax)? V spec 1.0 says "The
> vector floating-point vfmin and vfmax instructions have the same behavior
> as the corresponding scalar floating-point instructions in version 2.2 of
> the RISC-V F/D/Q extension.". And version 2.2 of F/D/Q (which is *not*
> version 2.2 of the instruction set, it's later than that) changed the
Oh, thanks for catching this - I indeed incorrectly assumed this refers to
version 2.2 of the RISC-V spec (which contains F/D, .. of version 2.0).
Too bad, it appeared too convenient. Then I need to add the same
!HONOR_SNANS to all the expanders as well as the tests.
Regards
Robin
LGTM as long as you add HONOR_SNANS
juzhe.zhong@rivai.ai
From: Robin Dapp
Date: 2023-10-31 03:26
To: Joseph Myers
CC: rdapp.gcc; gcc-patches; palmer; Kito Cheng; jeffreyalaw; juzhe.zhong@rivai.ai
Subject: Re: [PATCH] RISC-V: Add vector fmin/fmax expanders.
> Aren't they actually the IEEE 754-2019 operations (with different
> signaling NaN semantics; C functions such as fmaximum in C23), not the
> IEEE 754-2008 operations (C functions such as fmax)? V spec 1.0 says "The
> vector floating-point vfmin and vfmax instructions have the same behavior
> as the corresponding scalar floating-point instructions in version 2.2 of
> the RISC-V F/D/Q extension.". And version 2.2 of F/D/Q (which is *not*
> version 2.2 of the instruction set, it's later than that) changed the
Oh, thanks for catching this - I indeed incorrectly assumed this refers to
version 2.2 of the RISC-V spec (which contains F/D, .. of version 2.0).
Too bad, it appeared too convenient. Then I need to add the same
!HONOR_SNANS to all the expanders as well as the tests.
Regards
Robin
Thanks, going to commit the attached.
Regards
Robin
This patch adds expanders for fmin and fmax. As per RISC-V V Spec 1.0
vfmin/vfmax are IEEE 754-2019 compliant which differs from IEEE 754-2008
that fmin/fmax require (particularly in the signaling-NaN handling).
Therefore the pattern conditions include a !HONOR_SNANS.
gcc/ChangeLog:
* config/riscv/autovec.md (<ieee_fmaxmin_op><mode>3): fmax/fmin
expanders.
(cond_<ieee_fmaxmin_op><mode>): Ditto.
(cond_len_<ieee_fmaxmin_op><mode>): Ditto.
(reduc_fmax_scal_<mode>): Ditto.
(reduc_fmin_scal_<mode>): Ditto.
* config/riscv/riscv-v.cc (needs_fp_rounding): Add fmin/fmax.
* config/riscv/vector-iterators.md (fmin): New UNSPEC.
(UNSPEC_VFMIN): Ditto.
* config/riscv/vector.md (@pred_<ieee_fmaxmin_op><mode>): Add
UNSPEC insn patterns.
(@pred_<ieee_fmaxmin_op><mode>_scalar): Ditto.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c: Remove
-ffast-math.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/binop/fmax-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c: New test.
* gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_run_zvfh-10.c: New test.
* gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c: New test.
---
gcc/config/riscv/autovec.md | 72 +++++++++++++++++++
gcc/config/riscv/riscv-v.cc | 2 +
gcc/config/riscv/vector-iterators.md | 8 +++
gcc/config/riscv/vector.md | 43 +++++++++++
.../riscv/rvv/autovec/binop/fmax-1.c | 24 +++++++
.../riscv/rvv/autovec/binop/fmax_run-1.c | 47 ++++++++++++
.../riscv/rvv/autovec/binop/fmax_zvfh-1.c | 23 ++++++
.../riscv/rvv/autovec/binop/fmax_zvfh_run-1.c | 48 +++++++++++++
.../riscv/rvv/autovec/binop/fmin-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_run-1.c | 5 ++
.../riscv/rvv/autovec/binop/fmin_zvfh-1.c | 10 +++
.../riscv/rvv/autovec/binop/fmin_zvfh_run-1.c | 5 ++
.../riscv/rvv/autovec/cond/cond_fmax-1.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax-3.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax-4.c | 6 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-1.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-3.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_run-4.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-1.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-2.c | 32 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-3.c | 33 +++++++++
.../rvv/autovec/cond/cond_fmax_zvfh_run-4.c | 33 +++++++++
.../riscv/rvv/autovec/cond/cond_fmin-1.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-2.c | 3 +-
.../riscv/rvv/autovec/cond/cond_fmin-3.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin-4.c | 5 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-1.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-2.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-3.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_run-4.c | 2 +-
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c | 11 +++
.../riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c | 11 +++
.../rvv/autovec/cond/cond_fmin_zvfh_run-1.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-2.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-3.c | 5 ++
.../rvv/autovec/cond/cond_fmin_zvfh_run-4.c | 5 ++
.../riscv/rvv/autovec/reduc/reduc-10.c | 26 +++++++
.../riscv/rvv/autovec/reduc/reduc_run-10.c | 41 +++++++++++
.../riscv/rvv/autovec/reduc/reduc_zvfh-10.c | 24 +++++++
.../rvv/autovec/reduc/reduc_zvfh_run-10.c | 41 +++++++++++
48 files changed, 790 insertions(+), 25 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 9803f7524d7..f5e3e347ace 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -1436,6 +1436,22 @@ (define_insn_and_split "<optab><mode>3"
}
[(set_attr "type" "vfminmax")])
+(define_insn_and_split "<ieee_fmaxmin_op><mode>3"
+ [(set (match_operand:V_VLSF 0 "register_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 1 "register_operand")
+ (match_operand:V_VLSF 2 "register_operand")] UNSPEC_VFMAXMIN))]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode) && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ riscv_vector::emit_vlmax_insn (code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode),
+ riscv_vector::BINARY_OP, operands);
+ DONE;
+}
+[(set_attr "type" "vfminmax")])
+
;; -------------------------------------------------------------------------------
;; ---- [FP] Sign copying
;; -------------------------------------------------------------------------------
@@ -1736,6 +1752,36 @@ (define_expand "cond_len_<optab><mode>"
DONE;
})
+(define_expand "cond_<ieee_fmaxmin_op><mode>"
+ [(match_operand:V_VLSF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 2 "register_operand")
+ (match_operand:V_VLSF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 4 "autovec_else_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_binop (icode, operands);
+ DONE;
+})
+
+(define_expand "cond_len_<ieee_fmaxmin_op><mode>"
+ [(match_operand:VF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:VF
+ [(match_operand:VF 2 "register_operand")
+ (match_operand:VF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:VF 4 "autovec_else_operand")
+ (match_operand 5 "autovec_length_operand")
+ (match_operand 6 "const_0_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_len_binop (icode, operands);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [INT] Conditional ternary operations
;; -------------------------------------------------------------------------
@@ -2092,6 +2138,32 @@ (define_expand "reduc_smin_scal_<mode>"
DONE;
})
+(define_expand "reduc_fmax_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, true);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
+(define_expand "reduc_fmin_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR && !HONOR_SNANS (<MODE>mode)"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, false);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [FP] Left-to-right reductions
;; -------------------------------------------------------------------------
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index ee631404b44..3a49ae76426 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -3211,7 +3211,9 @@ needs_fp_rounding (unsigned icode, machine_mode mode)
return false;
return icode != maybe_code_for_pred (SMIN, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMIN, mode)
&& icode != maybe_code_for_pred (SMAX, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMAX, mode)
&& icode != maybe_code_for_pred (NEG, mode)
&& icode != maybe_code_for_pred (ABS, mode)
/* narrower-FP -> FP */
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index e80a20dcfba..d9b5dec5edb 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -82,6 +82,9 @@ (define_c_enum "unspec" [
UNSPEC_VFFMA
+ UNSPEC_VFMAX
+ UNSPEC_VFMIN
+
;; Integer and Float Reduction
UNSPEC_REDUC
UNSPEC_REDUC_SUM
@@ -3479,6 +3482,11 @@ (define_int_attr ud_constraint [(UNSPEC_VSLIDEUP "=&vr,&vr,&vr,&vr") (UNSPEC_VSL
(define_int_attr UNSPEC [(UNSPEC_VSLIDE1UP "UNSPEC_VSLIDE1UP")
(UNSPEC_VSLIDE1DOWN "UNSPEC_VSLIDE1DOWN")])
+(define_int_iterator UNSPEC_VFMAXMIN [UNSPEC_VFMAX UNSPEC_VFMIN])
+
+(define_int_attr ieee_fmaxmin_op [(UNSPEC_VFMAX "fmax") (UNSPEC_VFMIN "fmin")])
+(define_int_attr IEEE_FMAXMIN_OP [(UNSPEC_VFMAX "UNSPEC_VFMAX") (UNSPEC_VFMIN "UNSPEC_VFMIN")])
+
(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
smax umax smin umin mult div udiv mod umod
])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index c4c136cb5d2..0297e4f0227 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -6103,6 +6103,27 @@ (define_insn "@pred_<optab><mode>"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>"
+ [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:V_VLSF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")
+ (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")]
+ UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
@@ -6149,6 +6170,28 @@ (define_insn "@pred_<optab><mode>_scalar"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>_scalar"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:VF
+ [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")
+ (vec_duplicate:VF
+ (match_operand:<VEL> 4 "register_operand" " f, f, f, f"))]
+ UNSPEC_VFMAXMIN)
+ (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vf\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
new file mode 100644
index 00000000000..d635499c017
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax-1.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f, float) \
+ T (FN, , double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
new file mode 100644
index 00000000000..31661ee8900
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_run-1.c
@@ -0,0 +1,47 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+#include "fmax-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ test_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
new file mode 100644
index 00000000000..c137955619f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh-1.c
@@ -0,0 +1,23 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f16, _Float16) \
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
new file mode 100644
index 00000000000..4a248c28e0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmax_zvfh_run-1.c
@@ -0,0 +1,48 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+#include "fmax_zvfh-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ kest_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
new file mode 100644
index 00000000000..0d2b53e21dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
new file mode 100644
index 00000000000..1964137347f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
new file mode 100644
index 00000000000..39643a71f25
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
new file mode 100644
index 00000000000..05bfce42e9a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
index c5167b54fb3..25c35cf0607 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-1.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,11 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
index 30b6ae62777..17f86238b0f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-2.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
index 4521f588f1c..9a29b52de3d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-3.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,11 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
index 251066e4884..cba6cdf2a0f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax-4.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,11 +25,10 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
index e136f98002e..3dc1fb8bd46 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-1.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-1.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
index 291cfca14ef..0cf67561c4d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-2.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-2.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
index 34f011dadee..df4a5ded974 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-3.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-3.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
index 9986f8d24fe..1b949517637 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_run-4.c
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include "cond_fmax-4.c"
+#include <math.h>
#define N 99
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
new file mode 100644
index 00000000000..c6929a7c101
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
new file mode 100644
index 00000000000..b8a184161f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-2.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE) \
+ T (FN, TYPE, zero, 0) \
+ T (FN, TYPE, one, 1) \
+ T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
new file mode 100644
index 00000000000..af06f11b99d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 4; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
new file mode 100644
index 00000000000..e6a5a76ca46
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh-4.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 0; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
new file mode 100644
index 00000000000..1609d2ced7b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-1.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
new file mode 100644
index 00000000000..6c33858cc40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-2.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-2.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
new file mode 100644
index 00000000000..6df48c220f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-3.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-3.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
new file mode 100644
index 00000000000..9bb1beb1418
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmax_zvfh_run-4.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include "cond_fmax_zvfh-4.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
index 9e3fd290474..2c8fbfb0c9e 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-1.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-1.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
index c48fab461ff..fe0455412ba 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-2.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
index e916008ebf0..e76361c94ba 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-3.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-3.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
index 2c2edc2933b..9399a4027ff 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin-4.c
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-4.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
index 293e1d93307..139f9f77b34 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-1.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
index 3310bb7989f..e9449b8adcb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-2.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
index 6bed341ac87..f70c3440a21 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-3.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
index 4af0322e73f..fe700a2d5f6 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_run-4.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
new file mode 100644
index 00000000000..77bc6e7a77e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
new file mode 100644
index 00000000000..8e330afac83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-2.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
new file mode 100644
index 00000000000..5caeac9b4e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-3.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
new file mode 100644
index 00000000000..8281dc688e7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-4.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+/* { dg-final { scan-assembler-not {\tvf?merge\.v[vxi]m\t} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
new file mode 100644
index 00000000000..b334f4d6bea
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-1.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-1.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
new file mode 100644
index 00000000000..873f413c6b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-2.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-2.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
new file mode 100644
index 00000000000..94be087fb6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-3.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-3.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
new file mode 100644
index 00000000000..8a144e85afa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/cond/cond_fmin_zvfh_run-4.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -fno-signaling-nans" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-4.c"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
new file mode 100644
index 00000000000..be339bdd550
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc-10.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (float, max, __builtin_fmaxf) \
+ T (double, max, __builtin_fmax) \
+ T (float, min, __builtin_fminf) \
+ T (double, min, __builtin_fmin)
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
new file mode 100644
index 00000000000..6dc372f5fb6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_run-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+
+#include "reduc-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
new file mode 100644
index 00000000000..0651e3177b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh-10.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0 -fno-signaling-nans" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (_Float16, max, __builtin_fmaxf16) \
+ T (_Float16, min, __builtin_fminf16) \
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
new file mode 100644
index 00000000000..2b8bcdfe8fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/reduc/reduc_zvfh_run-10.c
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-signaling-nans" } */
+
+#include <math.h>
+
+#include "reduc_zvfh-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
@@ -1441,6 +1441,22 @@ (define_insn_and_split "<optab><mode>3"
}
[(set_attr "type" "vfminmax")])
+(define_insn_and_split "<ieee_fmaxmin_op><mode>3"
+ [(set (match_operand:V_VLSF 0 "register_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 1 "register_operand")
+ (match_operand:V_VLSF 2 "register_operand")] UNSPEC_VFMAXMIN))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ riscv_vector::emit_vlmax_insn (code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode),
+ riscv_vector::BINARY_OP, operands);
+ DONE;
+}
+[(set_attr "type" "vfminmax")])
+
;; -------------------------------------------------------------------------------
;; ---- [FP] Sign copying
;; -------------------------------------------------------------------------------
@@ -1741,6 +1757,36 @@ (define_expand "cond_len_<optab><mode>"
DONE;
})
+(define_expand "cond_<ieee_fmaxmin_op><mode>"
+ [(match_operand:V_VLSF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 2 "register_operand")
+ (match_operand:V_VLSF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 4 "autovec_else_operand")]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_binop (icode, operands);
+ DONE;
+})
+
+(define_expand "cond_len_<ieee_fmaxmin_op><mode>"
+ [(match_operand:VF 0 "register_operand")
+ (match_operand:<VM> 1 "vector_mask_operand")
+ (unspec:VF
+ [(match_operand:VF 2 "register_operand")
+ (match_operand:VF 3 "register_operand")] UNSPEC_VFMAXMIN)
+ (match_operand:VF 4 "autovec_else_operand")
+ (match_operand 5 "autovec_length_operand")
+ (match_operand 6 "const_0_operand")]
+ "TARGET_VECTOR"
+{
+ insn_code icode = code_for_pred (<IEEE_FMAXMIN_OP>, <MODE>mode);
+ riscv_vector::expand_cond_len_binop (icode, operands);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [INT] Conditional ternary operations
;; -------------------------------------------------------------------------
@@ -2097,6 +2143,32 @@ (define_expand "reduc_smin_scal_<mode>"
DONE;
})
+(define_expand "reduc_fmax_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, true);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
+(define_expand "reduc_fmin_scal_<mode>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:V_VLSF 1 "register_operand")]
+ "TARGET_VECTOR"
+{
+ REAL_VALUE_TYPE rv;
+ real_inf (&rv, false);
+ rtx f = const_double_from_real_value (rv, <VEL>mode);
+ riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, riscv_vector::REDUCE_OP,
+ operands, f);
+ DONE;
+})
+
;; -------------------------------------------------------------------------
;; ---- [FP] Left-to-right reductions
;; -------------------------------------------------------------------------
@@ -3207,7 +3207,9 @@ needs_fp_rounding (unsigned icode, machine_mode mode)
return false;
return icode != maybe_code_for_pred (SMIN, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMIN, mode)
&& icode != maybe_code_for_pred (SMAX, mode)
+ && icode != maybe_code_for_pred (UNSPEC_VFMAX, mode)
&& icode != maybe_code_for_pred (NEG, mode)
&& icode != maybe_code_for_pred (ABS, mode)
/* narrower-FP -> FP */
@@ -82,6 +82,9 @@ (define_c_enum "unspec" [
UNSPEC_VFFMA
+ UNSPEC_VFMAX
+ UNSPEC_VFMIN
+
;; Integer and Float Reduction
UNSPEC_REDUC
UNSPEC_REDUC_SUM
@@ -3479,6 +3482,11 @@ (define_int_attr ud_constraint [(UNSPEC_VSLIDEUP "=&vr,&vr,&vr,&vr") (UNSPEC_VSL
(define_int_attr UNSPEC [(UNSPEC_VSLIDE1UP "UNSPEC_VSLIDE1UP")
(UNSPEC_VSLIDE1DOWN "UNSPEC_VSLIDE1DOWN")])
+(define_int_iterator UNSPEC_VFMAXMIN [UNSPEC_VFMAX UNSPEC_VFMIN])
+
+(define_int_attr ieee_fmaxmin_op [(UNSPEC_VFMAX "fmax") (UNSPEC_VFMIN "fmin")])
+(define_int_attr IEEE_FMAXMIN_OP [(UNSPEC_VFMAX "UNSPEC_VFMAX") (UNSPEC_VFMIN "UNSPEC_VFMIN")])
+
(define_code_iterator any_int_binop [plus minus and ior xor ashift ashiftrt lshiftrt
smax umax smin umin mult div udiv mod umod
])
@@ -6085,6 +6085,27 @@ (define_insn "@pred_<optab><mode>"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>"
+ [(set (match_operand:V_VLSF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:V_VLSF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:V_VLSF
+ [(match_operand:V_VLSF 3 "register_operand" " vr, vr, vr, vr")
+ (match_operand:V_VLSF 4 "register_operand" " vr, vr, vr, vr")]
+ UNSPEC_VFMAXMIN)
+ (match_operand:V_VLSF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vv\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
@@ -6131,6 +6152,28 @@ (define_insn "@pred_<optab><mode>_scalar"
[(set_attr "type" "<float_insn_type>")
(set_attr "mode" "<MODE>")])
+(define_insn "@pred_<ieee_fmaxmin_op><mode>_scalar"
+ [(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
+ (if_then_else:VF
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm, vm,Wc1,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:VF
+ [(match_operand:VF 3 "register_operand" " vr, vr, vr, vr")
+ (vec_duplicate:VF
+ (match_operand:<VEL> 4 "register_operand" " f, f, f, f"))]
+ UNSPEC_VFMAXMIN)
+ (match_operand:VF 2 "vector_merge_operand" " vu, 0, vu, 0")))]
+ "TARGET_VECTOR"
+ "v<ieee_fmaxmin_op>.vf\t%0,%3,%4%p1"
+ [(set_attr "type" "vfminmax")
+ (set_attr "mode" "<MODE>")])
+
(define_insn "@pred_<optab><mode>_scalar"
[(set (match_operand:VF 0 "register_operand" "=vd, vd, vr, vr")
(if_then_else:VF
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f, float) \
+ T (FN, , double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
new file mode 100644
@@ -0,0 +1,47 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+#include "fmax-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ test_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, SUFFIX, TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict x, TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (SUFFIX) (x[i], y[i]); \
+ }
+
+#define TEST_ALL(T) \
+ T (FN, f16, _Float16) \
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
new file mode 100644
@@ -0,0 +1,48 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+#include "fmax_zvfh-1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, SUFFIX, TYPE) \
+ { \
+ TYPE dst[N], x[N], y[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ x[i] = i; \
+ dst[i] = i; \
+ y[i] = ((i & 1) - 1) * i * i; \
+ } \
+ y[0] = -0.0; \
+ y[1] = 0.0; \
+ y[2] = nan ("0.0"); \
+ y[3] = INFINITY; \
+ y[4] = -INFINITY; \
+ x[5] = -0.0; \
+ x[6] = 0.0; \
+ x[7] = nan ("0.0"); \
+ x[8] = INFINITY; \
+ x[9] = -INFINITY; \
+ dst[5] = -0.0; \
+ dst[6] = 0.0; \
+ dst[7] = nan ("0.0"); \
+ dst[8] = INFINITY; \
+ dst[9] = -INFINITY; \
+ kest_##TYPE (dst, y, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double ref = FN (SUFFIX) (x[i], y[i]); \
+ if (dst[i] != ref) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+
+int __attribute__ ((optimize ("1"))) main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 2 } } */
+
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_run-1.c"
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+} 1 } } */
+
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmax_zvfh_run-1.c"
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,9 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,9 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#ifndef FN
#define FN(X) __builtin_fmax##X
@@ -24,10 +25,9 @@
T (FN, TYPE, PRED_TYPE, two, 2)
#define TEST_ALL(T) \
- TEST_TYPE (T, FN (f16), _Float16, int16_t) \
TEST_TYPE (T, FN (f32), float, int32_t) \
TEST_TYPE (T, FN (f64), double, int64_t)
TEST_ALL (DEF_LOOP)
-/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-1.c"
+#include <math.h>
#define N 99
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-2.c"
+#include <math.h>
#define N 99
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-3.c"
+#include <math.h>
#define N 99
@@ -1,7 +1,8 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include "cond_fmax-4.c"
+#include <math.h>
#define N 99
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE) \
+ T (FN, TYPE, zero, 0) \
+ T (FN, TYPE, one, 1) \
+ T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 4; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 0; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {vfmax\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
new file mode 100644
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-1.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,32 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-2.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-3.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,33 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include "cond_fmax_zvfh-4.c"
+#include <math.h>
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
@@ -1,10 +1,11 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-1.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-2.c"
@@ -1,9 +1,10 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-3.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
@@ -1,9 +1,10 @@
/* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#include <stdint-gcc.h>
+#include <math.h>
#define FN(X) __builtin_fmin##X
#include "cond_fmax-4.c"
-/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 9 } } */
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 6 } } */
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-1.c"
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-2.c"
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-3.c"
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_v } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model -ffast-math" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
#define FN(X) __builtin_fmin##X
#include "cond_fmax_run-4.c"
new file mode 100644
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-1.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
+
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-2.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-3.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
new file mode 100644
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#include <stdint-gcc.h>
+#include <math.h>
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh-4.c"
+
+/* { dg-final { scan-assembler-times {vfmin\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v0.t} 3 } } */
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-1.c"
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-2.c"
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-3.c"
new file mode 100644
@@ -0,0 +1,5 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmax_zvfh_run-4.c"
new file mode 100644
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (float, max, __builtin_fmaxf) \
+ T (double, max, __builtin_fmax) \
+ T (float, min, __builtin_fminf) \
+ T (double, min, __builtin_fmin)
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
new file mode 100644
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_v } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+
+#include "reduc-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,41 @@
+/* { dg-do run { target { riscv_zvfh } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+
+#include <math.h>
+
+#include "reduc_zvfh-10.c"
+
+#define NUM_ELEMS(TYPE) (73 + sizeof (TYPE))
+
+#define INIT_VECTOR(TYPE) \
+ TYPE a[NUM_ELEMS (TYPE) + 1]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE) + 1; i++) \
+ { \
+ a[i] = ((i * 2) * (i & 1 ? 1 : -1) | 3); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ a[0] = -0.0; \
+ a[1] = nan ("0.0"); \
+ a[2] = nan ("1.0"); \
+ a[3] = 0.0; \
+ a[4] = -INFINITY; \
+ a[5] = INFINITY; \
+
+#define TEST_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ { \
+ INIT_VECTOR (TYPE); \
+ TYPE r1 = reduc_##NAME##_##TYPE (a, NUM_ELEMS (TYPE)); \
+ volatile TYPE r2 = -0.0; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r2 = MAXMIN_OP (r2, a[i]); \
+ if (r1 != r2) \
+ __builtin_abort (); \
+ }
+
+__attribute__ ((optimize ("1")))
+int main ()
+{
+ TEST_FMAXMIN (TEST_REDUC_FMAXMIN)
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable --param vect-epilogues-nomask=0" } */
+
+#include <stdint-gcc.h>
+
+#define DEF_REDUC_FMAXMIN(TYPE, NAME, MAXMIN_OP) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ reduc_##NAME##_##TYPE (TYPE *a, int n) \
+ { \
+ TYPE r = -0.0; \
+ for (int i = 0; i < n; ++i) \
+ r = MAXMIN_OP (r, a[i]); \
+ return r; \
+ }
+
+#define TEST_FMAXMIN(T) \
+ T (_Float16, max, __builtin_fmaxf16) \
+ T (_Float16, min, __builtin_fminf16) \
+
+
+TEST_FMAXMIN (DEF_REDUC_FMAXMIN)
+
+/* { dg-final { scan-assembler-times {vfredmax\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {vfredmin\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 1 } } */