[v2] RISC-V: Add autovec FP binary operations.

Message ID 56ca29ea-febe-c410-c042-2067b0e68dfa@gmail.com
State Superseded
Headers
Series [v2] RISC-V: Add autovec FP binary operations. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_check--master-arm fail Patch failed to apply

Commit Message

Robin Dapp June 15, 2023, 3:10 p.m. UTC
  Hi,

changes from V1:
 - Add VF_AUTO iterator and use it.
 - Ensured we don't ICE with -march=rv64gcv_zfhmin.

this implements the floating-point autovec expanders for binary
operations: vfadd, vfsub, vfdiv, vfmul, vfmax, vfmin and adds
tests.

The existing tests are split up into non-_Float16 and _Float16
flavors as we cannot rely on the zvfh extension being present.

As long as we do not have full middle-end support we need
-ffast-math for the tests.

gcc/ChangeLog:

	* config/riscv/autovec.md (<optab><mode>3): Implement binop
	expander.
	* config/riscv/riscv-protos.h (emit_vlmax_fp_insn): Declare.
	(emit_vlmax_fp_minmax_insn): Declare.
	(enum frm_field_enum): Rename this...
	(enum rounding_mode): ...to this.
	* config/riscv/riscv-v.cc (emit_vlmax_fp_insn): New function
	(emit_vlmax_fp_minmax_insn): New function.
	* config/riscv/riscv.cc (riscv_const_insns): Clarify const
	vector handling.
	(riscv_libgcc_floating_mode_supported_p): Adjust comment.
	(riscv_excess_precision): Do not convert to float for ZVFH.
	* config/riscv/vector-iterators.md: Add VF_AUTO iterator.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/autovec/binop/vadd-run.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vadd-template.h: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vdiv-run.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vdiv-template.h: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmax-run.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmax-template.h: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmin-run.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmin-template.h: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmul-run.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vmul-template.h: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vsub-run.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vsub-template.h: Add FP.
	* gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c: New test.
	* gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c: New test.
	* gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c: New test.
	* gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c: New test.
	* gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c: New test.
	* gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c: New test.
---
 gcc/config/riscv/autovec.md                   | 36 +++++++++
 gcc/config/riscv/riscv-protos.h               |  5 +-
 gcc/config/riscv/riscv-v.cc                   | 74 ++++++++++++++++++-
 gcc/config/riscv/riscv.cc                     | 27 +++++--
 gcc/config/riscv/vector-iterators.md          | 28 +++++++
 .../riscv/rvv/autovec/binop/vadd-run.c        | 12 ++-
 .../riscv/rvv/autovec/binop/vadd-rv32gcv.c    |  3 +-
 .../riscv/rvv/autovec/binop/vadd-rv64gcv.c    |  3 +-
 .../riscv/rvv/autovec/binop/vadd-template.h   | 11 ++-
 .../riscv/rvv/autovec/binop/vadd-zvfh-run.c   | 54 ++++++++++++++
 .../riscv/rvv/autovec/binop/vdiv-run.c        |  8 +-
 .../riscv/rvv/autovec/binop/vdiv-rv32gcv.c    |  7 +-
 .../riscv/rvv/autovec/binop/vdiv-rv64gcv.c    |  7 +-
 .../riscv/rvv/autovec/binop/vdiv-template.h   |  8 +-
 .../riscv/rvv/autovec/binop/vdiv-zvfh-run.c   | 37 ++++++++++
 .../riscv/rvv/autovec/binop/vmax-run.c        |  9 ++-
 .../riscv/rvv/autovec/binop/vmax-rv32gcv.c    |  3 +-
 .../riscv/rvv/autovec/binop/vmax-rv64gcv.c    |  3 +-
 .../riscv/rvv/autovec/binop/vmax-template.h   |  8 +-
 .../riscv/rvv/autovec/binop/vmax-zvfh-run.c   | 38 ++++++++++
 .../riscv/rvv/autovec/binop/vmin-run.c        | 10 ++-
 .../riscv/rvv/autovec/binop/vmin-rv32gcv.c    |  3 +-
 .../riscv/rvv/autovec/binop/vmin-rv64gcv.c    |  3 +-
 .../riscv/rvv/autovec/binop/vmin-template.h   |  8 +-
 .../riscv/rvv/autovec/binop/vmin-zvfh-run.c   | 37 ++++++++++
 .../riscv/rvv/autovec/binop/vmul-run.c        |  8 +-
 .../riscv/rvv/autovec/binop/vmul-rv32gcv.c    |  7 +-
 .../riscv/rvv/autovec/binop/vmul-rv64gcv.c    |  7 +-
 .../riscv/rvv/autovec/binop/vmul-template.h   |  8 +-
 .../riscv/rvv/autovec/binop/vmul-zvfh-run.c   | 37 ++++++++++
 .../riscv/rvv/autovec/binop/vrem-rv32gcv.c    |  3 +-
 .../riscv/rvv/autovec/binop/vsub-run.c        | 12 ++-
 .../riscv/rvv/autovec/binop/vsub-rv32gcv.c    |  8 +-
 .../riscv/rvv/autovec/binop/vsub-rv64gcv.c    |  8 +-
 .../riscv/rvv/autovec/binop/vsub-template.h   | 16 +++-
 .../riscv/rvv/autovec/binop/vsub-zvfh-run.c   | 55 ++++++++++++++
 36 files changed, 555 insertions(+), 56 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
  

Comments

Michael Collison June 15, 2023, 4:33 p.m. UTC | #1
Robin,

Why do we need '-ffast-math' with the tests?

On 6/15/23 11:10, Robin Dapp via Gcc-patches wrote:
> Hi,
>
> changes from V1:
>   - Add VF_AUTO iterator and use it.
>   - Ensured we don't ICE with -march=rv64gcv_zfhmin.
>
> this implements the floating-point autovec expanders for binary
> operations: vfadd, vfsub, vfdiv, vfmul, vfmax, vfmin and adds
> tests.
>
> The existing tests are split up into non-_Float16 and _Float16
> flavors as we cannot rely on the zvfh extension being present.
>
> As long as we do not have full middle-end support we need
> -ffast-math for the tests.
>
> gcc/ChangeLog:
>
> 	* config/riscv/autovec.md (<optab><mode>3): Implement binop
> 	expander.
> 	* config/riscv/riscv-protos.h (emit_vlmax_fp_insn): Declare.
> 	(emit_vlmax_fp_minmax_insn): Declare.
> 	(enum frm_field_enum): Rename this...
> 	(enum rounding_mode): ...to this.
> 	* config/riscv/riscv-v.cc (emit_vlmax_fp_insn): New function
> 	(emit_vlmax_fp_minmax_insn): New function.
> 	* config/riscv/riscv.cc (riscv_const_insns): Clarify const
> 	vector handling.
> 	(riscv_libgcc_floating_mode_supported_p): Adjust comment.
> 	(riscv_excess_precision): Do not convert to float for ZVFH.
> 	* config/riscv/vector-iterators.md: Add VF_AUTO iterator.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/rvv/autovec/binop/vadd-run.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vadd-template.h: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vdiv-run.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vdiv-template.h: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmax-run.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmax-template.h: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmin-run.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmin-template.h: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmul-run.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vmul-template.h: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vsub-run.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vsub-template.h: Add FP.
> 	* gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c: New test.
> 	* gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c: New test.
> 	* gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c: New test.
> 	* gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c: New test.
> 	* gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c: New test.
> 	* gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c: New test.
> ---
>   gcc/config/riscv/autovec.md                   | 36 +++++++++
>   gcc/config/riscv/riscv-protos.h               |  5 +-
>   gcc/config/riscv/riscv-v.cc                   | 74 ++++++++++++++++++-
>   gcc/config/riscv/riscv.cc                     | 27 +++++--
>   gcc/config/riscv/vector-iterators.md          | 28 +++++++
>   .../riscv/rvv/autovec/binop/vadd-run.c        | 12 ++-
>   .../riscv/rvv/autovec/binop/vadd-rv32gcv.c    |  3 +-
>   .../riscv/rvv/autovec/binop/vadd-rv64gcv.c    |  3 +-
>   .../riscv/rvv/autovec/binop/vadd-template.h   | 11 ++-
>   .../riscv/rvv/autovec/binop/vadd-zvfh-run.c   | 54 ++++++++++++++
>   .../riscv/rvv/autovec/binop/vdiv-run.c        |  8 +-
>   .../riscv/rvv/autovec/binop/vdiv-rv32gcv.c    |  7 +-
>   .../riscv/rvv/autovec/binop/vdiv-rv64gcv.c    |  7 +-
>   .../riscv/rvv/autovec/binop/vdiv-template.h   |  8 +-
>   .../riscv/rvv/autovec/binop/vdiv-zvfh-run.c   | 37 ++++++++++
>   .../riscv/rvv/autovec/binop/vmax-run.c        |  9 ++-
>   .../riscv/rvv/autovec/binop/vmax-rv32gcv.c    |  3 +-
>   .../riscv/rvv/autovec/binop/vmax-rv64gcv.c    |  3 +-
>   .../riscv/rvv/autovec/binop/vmax-template.h   |  8 +-
>   .../riscv/rvv/autovec/binop/vmax-zvfh-run.c   | 38 ++++++++++
>   .../riscv/rvv/autovec/binop/vmin-run.c        | 10 ++-
>   .../riscv/rvv/autovec/binop/vmin-rv32gcv.c    |  3 +-
>   .../riscv/rvv/autovec/binop/vmin-rv64gcv.c    |  3 +-
>   .../riscv/rvv/autovec/binop/vmin-template.h   |  8 +-
>   .../riscv/rvv/autovec/binop/vmin-zvfh-run.c   | 37 ++++++++++
>   .../riscv/rvv/autovec/binop/vmul-run.c        |  8 +-
>   .../riscv/rvv/autovec/binop/vmul-rv32gcv.c    |  7 +-
>   .../riscv/rvv/autovec/binop/vmul-rv64gcv.c    |  7 +-
>   .../riscv/rvv/autovec/binop/vmul-template.h   |  8 +-
>   .../riscv/rvv/autovec/binop/vmul-zvfh-run.c   | 37 ++++++++++
>   .../riscv/rvv/autovec/binop/vrem-rv32gcv.c    |  3 +-
>   .../riscv/rvv/autovec/binop/vsub-run.c        | 12 ++-
>   .../riscv/rvv/autovec/binop/vsub-rv32gcv.c    |  8 +-
>   .../riscv/rvv/autovec/binop/vsub-rv64gcv.c    |  8 +-
>   .../riscv/rvv/autovec/binop/vsub-template.h   | 16 +++-
>   .../riscv/rvv/autovec/binop/vsub-zvfh-run.c   | 55 ++++++++++++++
>   36 files changed, 555 insertions(+), 56 deletions(-)
>   create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
>   create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
>
> diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
> index 579cbb07234..94452c932a4 100644
> --- a/gcc/config/riscv/autovec.md
> +++ b/gcc/config/riscv/autovec.md
> @@ -769,3 +769,39 @@ (define_expand "vec_init<vi_half><mode>"
>   {
>     DONE;
>   })
> +
> +;; -------------------------------------------------------------------------
> +;; ---- [FP] Binary operations
> +;; -------------------------------------------------------------------------
> +;; Includes:
> +;; - vfadd.vv/vfsub.vv/...
> +;; - vfadd.vf/vfsub.vf/...
> +;; -------------------------------------------------------------------------
> +(define_expand "<optab><mode>3"
> +  [(match_operand:VF_AUTO 0 "register_operand")
> +   (any_float_binop:VF_AUTO
> +    (match_operand:VF_AUTO 1 "register_operand")
> +    (match_operand:VF_AUTO 2 "register_operand"))]
> +  "TARGET_VECTOR"
> +{
> +  riscv_vector::emit_vlmax_fp_insn (code_for_pred (<CODE>, <MODE>mode),
> +				    riscv_vector::RVV_BINOP, operands);
> +  DONE;
> +})
> +
> +;; -------------------------------------------------------------------------
> +;; Includes:
> +;; - vfmin.vv/vfmax.vv
> +;; - vfmin.vf/vfmax.vf
> +;; -------------------------------------------------------------------------
> +(define_expand "<optab><mode>3"
> +  [(match_operand:VF_AUTO 0 "register_operand")
> +   (any_float_binop_nofrm:VF_AUTO
> +    (match_operand:VF_AUTO 1 "register_operand")
> +    (match_operand:VF_AUTO 2 "register_operand"))]
> +  "TARGET_VECTOR"
> +{
> +  riscv_vector::emit_vlmax_fp_minmax_insn (code_for_pred (<CODE>, <MODE>mode),
> +					   riscv_vector::RVV_BINOP, operands);
> +  DONE;
> +})
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index f422adf8521..8e8f3b1f454 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -185,6 +185,8 @@ bool legitimize_move (rtx, rtx);
>   void emit_vlmax_vsetvl (machine_mode, rtx);
>   void emit_hard_vlmax_vsetvl (machine_mode, rtx);
>   void emit_vlmax_insn (unsigned, int, rtx *, rtx = 0);
> +void emit_vlmax_fp_insn (unsigned, int, rtx *, rtx = 0);
> +void emit_vlmax_fp_minmax_insn (unsigned, int, rtx *, rtx = 0);
>   void emit_vlmax_ternary_insn (unsigned, int, rtx *, rtx = 0);
>   void emit_nonvlmax_insn (unsigned, int, rtx *, rtx);
>   void emit_vlmax_slide_insn (unsigned, rtx *);
> @@ -260,11 +262,12 @@ enum vxrm_field_enum
>     VXRM_RDN,
>     VXRM_ROD
>   };
> +
>   /* Rounding mode bitfield for floating point FRM.  The value of enum comes
>      from the below link.
>      https://github.com/riscv/riscv-isa-manual/blob/main/src/f-st-ext.adoc#floating-point-control-and-status-register
>    */
> -enum frm_field_enum
> +enum rounding_mode
>   {
>     FRM_RNE = 0, /* Aka 0b000.  */
>     FRM_RTZ = 1, /* Aka 0b001.  */
> diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
> index 1c86cfbdcee..e4c6af83ffd 100644
> --- a/gcc/config/riscv/riscv-v.cc
> +++ b/gcc/config/riscv/riscv-v.cc
> @@ -74,8 +74,10 @@ public:
>       : m_opno (0), m_op_num (0), m_has_dest_p (false),
>         m_fully_unmasked_p (false), m_use_real_merge_p (false),
>         m_needs_avl_p (false), m_vlmax_p (false), m_has_tail_policy_p (false),
> -      m_has_mask_policy_p (false), m_tail_policy (TAIL_ANY),
> -      m_mask_policy (MASK_ANY), m_dest_mode (VOIDmode), m_mask_mode (VOIDmode),
> +      m_has_mask_policy_p (false), m_has_fp_rounding_mode_p (false),
> +      m_tail_policy (TAIL_ANY), m_mask_policy (MASK_ANY),
> +      m_fp_rounding_mode (FRM_DYN),
> +      m_dest_mode (VOIDmode), m_mask_mode (VOIDmode),
>         m_vl_op (NULL_RTX)
>     {}
>   
> @@ -87,8 +89,10 @@ public:
>         m_fully_unmasked_p (use_all_trues_mask_p),
>         m_use_real_merge_p (use_real_merge_p), m_needs_avl_p (needs_avl_p),
>         m_vlmax_p (vlmax_p), m_has_tail_policy_p (false),
> -      m_has_mask_policy_p (false), m_tail_policy (TAIL_ANY),
> -      m_mask_policy (MASK_ANY), m_dest_mode (dest_mode),
> +      m_has_mask_policy_p (false), m_has_fp_rounding_mode_p (false),
> +      m_tail_policy (TAIL_ANY), m_mask_policy (MASK_ANY),
> +      m_fp_rounding_mode (FRM_DYN),
> +      m_dest_mode (dest_mode),
>         m_mask_mode (mask_mode), m_vl_op (NULL_RTX)
>     {}
>   
> @@ -104,6 +108,12 @@ public:
>     }
>     void set_vl (rtx vl) { m_vl_op = vl; }
>   
> +  void set_rounding_mode (enum rounding_mode mode)
> +  {
> +    m_has_fp_rounding_mode_p = true;
> +    m_fp_rounding_mode = mode;
> +  }
> +
>     void add_output_operand (rtx x, machine_mode mode)
>     {
>       create_output_operand (&m_ops[m_opno++], x, mode);
> @@ -140,6 +150,15 @@ public:
>       add_input_operand (gen_int_mode (type, Pmode), Pmode);
>     }
>   
> +  void add_rounding_mode_operand ()
> +  {
> +    if (m_has_fp_rounding_mode_p)
> +      {
> +	rtx frm_rtx = gen_int_mode (m_fp_rounding_mode, Pmode);
> +	add_input_operand (frm_rtx, Pmode);
> +      }
> +  }
> +
>     void emit_insn (enum insn_code icode, rtx *ops)
>     {
>       int opno = 0;
> @@ -200,6 +219,9 @@ public:
>         add_policy_operand ();
>       if (m_needs_avl_p)
>         add_avl_type_operand (m_vlmax_p ? avl_type::VLMAX : avl_type::NONVLMAX);
> +
> +    add_rounding_mode_operand ();
> +
>       expand (icode, any_mem_p);
>     }
>   
> @@ -231,8 +253,10 @@ private:
>     bool m_vlmax_p;
>     bool m_has_tail_policy_p;
>     bool m_has_mask_policy_p;
> +  bool m_has_fp_rounding_mode_p;
>     enum tail_policy m_tail_policy;
>     enum mask_policy m_mask_policy;
> +  enum rounding_mode m_fp_rounding_mode;
>     machine_mode m_dest_mode;
>     machine_mode m_mask_mode;
>     rtx m_vl_op;
> @@ -653,6 +677,48 @@ emit_vlmax_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
>     e.emit_insn ((enum insn_code) icode, ops);
>   }
>   
> +void
> +emit_vlmax_fp_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
> +{
> +  machine_mode dest_mode = GET_MODE (ops[0]);
> +  machine_mode mask_mode = get_mask_mode (dest_mode).require ();
> +  insn_expander<RVV_INSN_OPERANDS_MAX> e (op_num,
> +					  /* HAS_DEST_P */ true,
> +					  /* FULLY_UNMASKED_P */ true,
> +					  /* USE_REAL_MERGE_P */ false,
> +					  /* HAS_AVL_P */ true,
> +					  /* VLMAX_P */ true,
> +					  dest_mode,
> +					  mask_mode);
> +
> +  e.set_policy (TAIL_ANY);
> +  e.set_policy (MASK_ANY);
> +  e.set_rounding_mode (FRM_DYN);
> +  e.set_vl (vl);
> +  e.emit_insn ((enum insn_code) icode, ops);
> +}
> +
> +void
> +emit_vlmax_fp_minmax_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
> +{
> +  machine_mode dest_mode = GET_MODE (ops[0]);
> +  machine_mode mask_mode = get_mask_mode (dest_mode).require ();
> +  insn_expander<RVV_INSN_OPERANDS_MAX> e (op_num,
> +					  /* HAS_DEST_P */ true,
> +					  /* FULLY_UNMASKED_P */ true,
> +					  /* USE_REAL_MERGE_P */ false,
> +					  /* HAS_AVL_P */ true,
> +					  /* VLMAX_P */ true,
> +					  dest_mode,
> +					  mask_mode);
> +
> +  e.set_policy (TAIL_ANY);
> +  e.set_policy (MASK_ANY);
> +
> +  e.set_vl (vl);
> +  e.emit_insn ((enum insn_code) icode, ops);
> +}
> +
>   /* This function emits a {VLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
>    * ternary operation which always has a real merge operand.  */
>   void
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index e5ae4e81b7a..c4588a55e04 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1306,11 +1306,22 @@ riscv_const_insns (rtx x)
>   		if (satisfies_constraint_vi (x))
>   		  return 1;
>   
> -		/* A const duplicate vector can always be broadcast from
> -		   a general-purpose register.  This means we need as many
> -		   insns as it takes to load the constant into the GPR
> -		   and one vmv.v.x.  */
> -		return 1 + riscv_const_insns (elt);
> +		/* Any int/FP constants can always be broadcast from a
> +		   scalar register.  Loading of a floating-point
> +		   constant incurs a literal-pool access.  Allow this in
> +		   order to increase vectorization possibilities.  */
> +		int n = riscv_const_insns (elt);
> +		if (CONST_DOUBLE_P (elt))
> +		    return 1 + 4; /* vfmv.v.f + memory access.  */
> +		else
> +		  {
> +		    /* We need as many insns as it takes to load the constant
> +		       into a GPR and one vmv.v.x.  */
> +		    if (n != 0)
> +		      return 1 + n;
> +		    else
> +		      return 1 + 4; /*vmv.v.x + memory access.  */
> +		  }
>   	      }
>   	  }
>   
> @@ -7209,8 +7220,8 @@ riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode)
>          precision of the _FloatN type; evaluate all other operations and
>          constants to the range and precision of the semantic type;
>   
> -   If we have the zfh/zhinx extensions then we support _Float16 in native
> -   precision, so we should set this to 16.  */
> +   If we have the zfh/zhinx/zvfh extensions then we support _Float16
> +   in native precision, so we should set this to 16.  */
>   static enum flt_eval_method
>   riscv_excess_precision (enum excess_precision_type type)
>   {
> @@ -7218,7 +7229,7 @@ riscv_excess_precision (enum excess_precision_type type)
>       {
>       case EXCESS_PRECISION_TYPE_FAST:
>       case EXCESS_PRECISION_TYPE_STANDARD:
> -      return ((TARGET_ZFH || TARGET_ZHINX)
> +      return ((TARGET_ZFH || TARGET_ZHINX || TARGET_ZVFH)
>   		? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
>   		: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
>       case EXCESS_PRECISION_TYPE_IMPLICIT:
> diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
> index 139d2b74d7c..e6040c1981c 100644
> --- a/gcc/config/riscv/vector-iterators.md
> +++ b/gcc/config/riscv/vector-iterators.md
> @@ -317,6 +317,34 @@ (define_mode_iterator VF [
>     (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
>   ])
>   
> +;; This iterator is the same as above but with TARGET_VECTOR_ELEN_FP_16
> +;; changed to TARGET_ZVFH.  TARGET_VECTOR_ELEN_FP_16 is also true for
> +;; TARGET_ZVFHMIN while we actually disable all instructions apart from
> +;; load, store and convert for it.
> +;; Consequently the autovec expanders should also only be enabled with
> +;; TARGET_ZVFH.
> +(define_mode_iterator VF_AUTO [
> +  (VNx1HF "TARGET_ZVFH && TARGET_MIN_VLEN < 128")
> +  (VNx2HF "TARGET_ZVFH")
> +  (VNx4HF "TARGET_ZVFH")
> +  (VNx8HF "TARGET_ZVFH")
> +  (VNx16HF "TARGET_ZVFH")
> +  (VNx32HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
> +  (VNx64HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
> +
> +  (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128")
> +  (VNx2SF "TARGET_VECTOR_ELEN_FP_32")
> +  (VNx4SF "TARGET_VECTOR_ELEN_FP_32")
> +  (VNx8SF "TARGET_VECTOR_ELEN_FP_32")
> +  (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
> +  (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128")
> +  (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128")
> +  (VNx2DF "TARGET_VECTOR_ELEN_FP_64")
> +  (VNx4DF "TARGET_VECTOR_ELEN_FP_64")
> +  (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
> +  (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
> +])
> +
>   (define_mode_iterator VI_HAS_HALF [
>      VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
>      (VNx32SI "TARGET_MIN_VLEN >= 128")
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
> index 65f61b0e932..7f05e589172 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
> @@ -51,7 +51,9 @@
>    RUN(int32_t, -3)	\
>    RUN(uint32_t, 4)	\
>    RUN(int64_t, -5)	\
> - RUN(uint64_t, 6)    \
> + RUN(uint64_t, 6)	\
> + RUN(float, -5)		\
> + RUN(double, 6)		\
>    RUN2(int8_t, -7)	\
>    RUN2(uint8_t, 8)	\
>    RUN2(int16_t, -7)	\
> @@ -59,7 +61,9 @@
>    RUN2(int32_t, -9)	\
>    RUN2(uint32_t, 10)	\
>    RUN2(int64_t, -11)	\
> - RUN2(uint64_t, 12)   \
> + RUN2(uint64_t, 12)	\
> + RUN2(float, -11)	\
> + RUN2(double, 12)	\
>    RUN3M(int8_t, 13)	\
>    RUN3(uint8_t, 14)	\
>    RUN3M(int16_t, 13)	\
> @@ -67,7 +71,9 @@
>    RUN3M(int32_t, 15)	\
>    RUN3(uint32_t, 16)	\
>    RUN3M(int64_t, 17)	\
> - RUN3(uint64_t, 18)
> + RUN3(uint64_t, 18)	\
> + RUN3(float, 17)	\
> + RUN3M(double, 18)	\
>   
>   int main ()
>   {
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
> index 2d094749c6a..cd0da74d8a5 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
> @@ -1,7 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vadd-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */
>   /* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */
> +/* { dg-final { scan-assembler-times {\tvfadd\.vv} 9 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
> index 4a1dc41c34a..30c3ef7bd4f 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
> @@ -1,7 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vadd-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */
>   /* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */
> +/* { dg-final { scan-assembler-times {\tvfadd\.vv} 9 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
> index fecf2947691..e05b9c76275 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
> @@ -41,6 +41,9 @@
>    TEST_TYPE(uint32_t)	\
>    TEST_TYPE(int64_t)	\
>    TEST_TYPE(uint64_t)    \
> + TEST_TYPE(_Float16)	\
> + TEST_TYPE(float)	\
> + TEST_TYPE(double)	\
>    TEST2_TYPE(int8_t)	\
>    TEST2_TYPE(uint8_t)	\
>    TEST2_TYPE(int16_t)	\
> @@ -49,6 +52,9 @@
>    TEST2_TYPE(uint32_t)	\
>    TEST2_TYPE(int64_t)	\
>    TEST2_TYPE(uint64_t)   \
> + TEST2_TYPE(_Float16)	\
> + TEST2_TYPE(float)	\
> + TEST2_TYPE(double)	\
>    TEST3M_TYPE(int8_t)	\
>    TEST3_TYPE(uint8_t)	\
>    TEST3M_TYPE(int16_t)	\
> @@ -56,6 +62,9 @@
>    TEST3M_TYPE(int32_t)	\
>    TEST3_TYPE(uint32_t)	\
>    TEST3M_TYPE(int64_t)	\
> - TEST3_TYPE(uint64_t)
> + TEST3_TYPE(uint64_t)   \
> + TEST3M_TYPE(_Float16)	\
> + TEST3_TYPE(float)	\
> + TEST3M_TYPE(double)	\
>   
>   TEST_ALL()
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
> new file mode 100644
> index 00000000000..595a5337939
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
> @@ -0,0 +1,54 @@
> +/* { dg-do run { target { riscv_zvfh_hw } } } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
> +
> +#include "vadd-template.h"
> +
> +#include <assert.h>
> +
> +#define SZ 512
> +
> +#define RUN(TYPE,VAL)				\
> +  TYPE a##TYPE[SZ];				\
> +  TYPE b##TYPE[SZ];	  			\
> +  for (int i = 0; i < SZ; i++)			\
> +  {                             		\
> +    a##TYPE[i] = 0;             		\
> +    b##TYPE[i] = VAL;           		\
> +  }                             		\
> +  vadd_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (a##TYPE[i] == VAL);
> +
> +#define RUN2(TYPE,VAL)				\
> +  TYPE as##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as##TYPE[i] = 0;            		\
> +  vadds_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as##TYPE[i] == VAL);
> +
> +#define RUN3(TYPE,VAL)				\
> +  TYPE ai##TYPE[SZ];	  	        	\
> +  for (int i = 0; i < SZ; i++)			\
> +    ai##TYPE[i] = VAL;				\
> +  vaddi_##TYPE (ai##TYPE, ai##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (ai##TYPE[i] == VAL + 15);
> +
> +#define RUN3M(TYPE,VAL)				\
> +  TYPE aim##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    aim##TYPE[i] = VAL;				\
> +  vaddim_##TYPE (aim##TYPE, aim##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (aim##TYPE[i] == VAL - 16);
> +
> +#define RUN_ALL()	\
> + RUN(_Float16, 4)	\
> + RUN2(_Float16, 10)	\
> + RUN3M(_Float16, 17)	\
> +
> +int main ()
> +{
> +  RUN_ALL()
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
> index 810757a8834..9960c399b1f 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
> @@ -1,5 +1,5 @@
>   /* { dg-do run { target { riscv_vector_hw } } } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vdiv-template.h"
>   
> @@ -36,6 +36,8 @@
>    RUN(uint32_t, 4)	\
>    RUN(int64_t, -5)	\
>    RUN(uint64_t, 6)	\
> + RUN(float, -5)		\
> + RUN(double, 6)		\
>    RUN2(int8_t, -7)	\
>    RUN2(uint8_t, 8)	\
>    RUN2(int16_t, -7)	\
> @@ -43,7 +45,9 @@
>    RUN2(int32_t, -9)	\
>    RUN2(uint32_t, 10)	\
>    RUN2(int64_t, -11)	\
> - RUN2(uint64_t, 12)
> + RUN2(uint64_t, 12)	\
> + RUN2(float, -11)	\
> + RUN2(double, 12)	\
>   
>   int main ()
>   {
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
> index 9f059ebc84c..604d9acb038 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
> @@ -1,5 +1,5 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vdiv-template.h"
>   
> @@ -8,3 +8,8 @@
>   
>   /* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */
>   /* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */
> +
> +/* Division by constant is done by calculating a reciprocal and
> +   then multiplying.  Hence we do not expect 6 vfdivs.  */
> +/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */
> +/* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
> index cd5d30b8974..26884035d57 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
> @@ -1,5 +1,5 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vdiv-template.h"
>   
> @@ -8,3 +8,8 @@
>   
>   /* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */
>   /* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */
> +
> +/* Division by constant is done by calculating a reciprocal and
> +   then multiplying.  Hence we do not expect 6 vfdivs.  */
> +/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */
> +/* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
> index fd9199722b6..7b0f579d1c9 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
> @@ -25,6 +25,9 @@
>    TEST_TYPE(uint32_t)	\
>    TEST_TYPE(int64_t)	\
>    TEST_TYPE(uint64_t)    \
> + TEST_TYPE(_Float16)	\
> + TEST_TYPE(float)	\
> + TEST_TYPE(double)	\
>    TEST2_TYPE(int8_t)	\
>    TEST2_TYPE(uint8_t)	\
>    TEST2_TYPE(int16_t)	\
> @@ -32,6 +35,9 @@
>    TEST2_TYPE(int32_t)	\
>    TEST2_TYPE(uint32_t)	\
>    TEST2_TYPE(int64_t)	\
> - TEST2_TYPE(uint64_t)
> + TEST2_TYPE(uint64_t)	\
> + TEST2_TYPE(_Float16)	\
> + TEST2_TYPE(float)	\
> + TEST2_TYPE(double)	\
>   
>   TEST_ALL()
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
> new file mode 100644
> index 00000000000..c1c84e87a7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
> @@ -0,0 +1,37 @@
> +/* { dg-do run { target { riscv_zvfh_hw } } } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
> +
> +#include "vdiv-template.h"
> +
> +#include <assert.h>
> +
> +#define SZ 512
> +
> +#define RUN(TYPE,VAL)				\
> +  TYPE a##TYPE[SZ];				\
> +  TYPE b##TYPE[SZ];	  			\
> +  for (int i = 0; i < SZ; i++)			\
> +  {                             		\
> +    a##TYPE[i] = VAL * 3;       		\
> +    b##TYPE[i] = VAL;           		\
> +  }                             		\
> +  vdiv_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (a##TYPE[i] == 3);
> +
> +#define RUN2(TYPE,VAL)				\
> +  TYPE as##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as##TYPE[i] = VAL * 5;			\
> +  vdivs_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as##TYPE[i] == 5);
> +
> +#define RUN_ALL()	\
> + RUN(_Float16, 4)	\
> + RUN2(_Float16, 10)	\
> +
> +int main ()
> +{
> +  RUN_ALL()
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
> index d889f28b298..da90fe8da33 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
> @@ -1,5 +1,5 @@
>   /* { dg-do run { target { riscv_vector_hw } } } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmax-template.h"
>   
> @@ -27,6 +27,7 @@
>     for (int i = 0; i < SZ; i++)			\
>       assert (as##TYPE[i] == 0 > VAL ? 0 : VAL);
>   
> +
>   #define RUN_ALL()	\
>    RUN(int8_t, -1)	\
>    RUN(uint8_t, 2)	\
> @@ -36,6 +37,8 @@
>    RUN(uint32_t, 4)	\
>    RUN(int64_t, -5)	\
>    RUN(uint64_t, 6)	\
> + RUN(float, -5)		\
> + RUN(double, 6)		\
>    RUN2(int8_t, -7)	\
>    RUN2(uint8_t, 8)	\
>    RUN2(int16_t, -7)	\
> @@ -43,7 +46,9 @@
>    RUN2(int32_t, -9)	\
>    RUN2(uint32_t, 10)	\
>    RUN2(int64_t, -11)	\
> - RUN2(uint64_t, 12)
> + RUN2(uint64_t, 12)	\
> + RUN2(float, -11)	\
> + RUN2(double, 12)	\
>   
>   int main ()
>   {
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
> index 7b217d990a6..fbfa3ab057d 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
> @@ -1,7 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmax-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvmax\.vv} 8 } } */
>   /* { dg-final { scan-assembler-times {\tvmaxu\.vv} 8 } } */
> +/* { dg-final { scan-assembler-times {\tvfmax\.vv} 6 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
> index 1b7f8c6be16..cf01ebc65f8 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
> @@ -1,7 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmax-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvmax\.vv} 8 } } */
>   /* { dg-final { scan-assembler-times {\tvmaxu\.vv} 8 } } */
> +/* { dg-final { scan-assembler-times {\tvfmax\.vv} 6 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
> index 6deb5126c7d..54828cd922a 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
> @@ -25,6 +25,9 @@
>    TEST_TYPE(uint32_t)	\
>    TEST_TYPE(int64_t)	\
>    TEST_TYPE(uint64_t)    \
> + TEST_TYPE(_Float16)	\
> + TEST_TYPE(float)	\
> + TEST_TYPE(double)	\
>    TEST2_TYPE(int8_t)	\
>    TEST2_TYPE(uint8_t)	\
>    TEST2_TYPE(int16_t)	\
> @@ -32,6 +35,9 @@
>    TEST2_TYPE(int32_t)	\
>    TEST2_TYPE(uint32_t)	\
>    TEST2_TYPE(int64_t)	\
> - TEST2_TYPE(uint64_t)
> + TEST2_TYPE(uint64_t)	\
> + TEST2_TYPE(_Float16)	\
> + TEST2_TYPE(float)	\
> + TEST2_TYPE(double)	\
>   
>   TEST_ALL()
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
> new file mode 100644
> index 00000000000..1ab3d5d1199
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
> @@ -0,0 +1,38 @@
> +/* { dg-do run { target { riscv_zvfh_hw } } } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
> +
> +#include "vmax-template.h"
> +
> +#include <assert.h>
> +
> +#define SZ 512
> +
> +#define RUN(TYPE,VAL)				\
> +  TYPE a##TYPE[SZ];				\
> +  TYPE b##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +  {                             		\
> +    a##TYPE[i] = 0;             		\
> +    b##TYPE[i] = VAL;           		\
> +  }                             		\
> +  vmax_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (a##TYPE[i] == 0 > VAL ? 0 : VAL);
> +
> +#define RUN2(TYPE,VAL)				\
> +  TYPE as##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as##TYPE[i] = 0;				\
> +  vmaxs_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as##TYPE[i] == 0 > VAL ? 0 : VAL);
> +
> +
> +#define RUN_ALL()	\
> + RUN(_Float16, 4)	\
> + RUN2(_Float16, 10)	\
> +
> +int main ()
> +{
> +  RUN_ALL()
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
> index a5887e6097f..e8ac9395d7b 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
> @@ -1,5 +1,5 @@
>   /* { dg-do run { target { riscv_vector_hw } } } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmin-template.h"
>   
> @@ -35,7 +35,9 @@
>    RUN(int32_t, -3)	\
>    RUN(uint32_t, 4)	\
>    RUN(int64_t, -5)	\
> - RUN(uint64_t, 6)    \
> + RUN(uint64_t, 6)	\
> + RUN(float, -5)		\
> + RUN(double, 6)		\
>    RUN2(int8_t, -7)	\
>    RUN2(uint8_t, 8)	\
>    RUN2(int16_t, -7)	\
> @@ -43,7 +45,9 @@
>    RUN2(int32_t, -9)	\
>    RUN2(uint32_t, 10)	\
>    RUN2(int64_t, -11)	\
> - RUN2(uint64_t, 12)
> + RUN2(uint64_t, 12)	\
> + RUN2(float, -11)	\
> + RUN2(double, 12)	\
>   
>   int main ()
>   {
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
> index bf826ebf53a..87640732b3b 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
> @@ -1,7 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmin-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvmin\.vv} 8 } } */
>   /* { dg-final { scan-assembler-times {\tvminu\.vv} 8 } } */
> +/* { dg-final { scan-assembler-times {\tvfmin\.vv} 6 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
> index f57d4369006..193dacc82c5 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
> @@ -1,7 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmin-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvmin\.vv} 8 } } */
>   /* { dg-final { scan-assembler-times {\tvminu\.vv} 8 } } */
> +/* { dg-final { scan-assembler-times {\tvfmin\.vv} 6 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
> index 1225d5aca64..ca0d4e751e3 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
> @@ -25,6 +25,9 @@
>    TEST_TYPE(uint32_t)	\
>    TEST_TYPE(int64_t)	\
>    TEST_TYPE(uint64_t)    \
> + TEST_TYPE(_Float16)	\
> + TEST_TYPE(float)	\
> + TEST_TYPE(double)	\
>    TEST2_TYPE(int8_t)	\
>    TEST2_TYPE(uint8_t)	\
>    TEST2_TYPE(int16_t)	\
> @@ -32,6 +35,9 @@
>    TEST2_TYPE(int32_t)	\
>    TEST2_TYPE(uint32_t)	\
>    TEST2_TYPE(int64_t)	\
> - TEST2_TYPE(uint64_t)
> + TEST2_TYPE(uint64_t)	\
> + TEST2_TYPE(_Float16)	\
> + TEST2_TYPE(float)	\
> + TEST2_TYPE(double)	\
>   
>   TEST_ALL()
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
> new file mode 100644
> index 00000000000..2d593542f0e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
> @@ -0,0 +1,37 @@
> +/* { dg-do run { target { riscv_zvfh_hw } } } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
> +
> +#include "vmin-template.h"
> +
> +#include <assert.h>
> +
> +#define SZ 512
> +
> +#define RUN(TYPE,VAL)				\
> +  TYPE a##TYPE[SZ];				\
> +  TYPE b##TYPE[SZ];	  			\
> +  for (int i = 0; i < SZ; i++)			\
> +  {                             		\
> +    a##TYPE[i] = 0;             		\
> +    b##TYPE[i] = VAL;           		\
> +  }                             		\
> +  vmin_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (a##TYPE[i] == 0 < VAL ? 0 : VAL);
> +
> +#define RUN2(TYPE,VAL)				\
> +  TYPE as##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as##TYPE[i] = 0;				\
> +  vmins_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as##TYPE[i] == 0 < VAL ? 0 : VAL);
> +
> +#define RUN_ALL()	\
> + RUN(_Float16, 4)	\
> + RUN2(_Float16, 10)	\
> +
> +int main ()
> +{
> +  RUN_ALL()
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
> index 22a2c1a18bb..60d0c906107 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
> @@ -1,5 +1,5 @@
>   /* { dg-do run { target { riscv_vector_hw } } } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmul-template.h"
>   
> @@ -36,6 +36,8 @@
>    RUN(uint32_t, 4)	\
>    RUN(int64_t, -5)	\
>    RUN(uint64_t, 6)	\
> + RUN(float, -5)		\
> + RUN(double, 6)		\
>    RUN2(int8_t, -7)	\
>    RUN2(uint8_t, 8)	\
>    RUN2(int16_t, -7)	\
> @@ -43,7 +45,9 @@
>    RUN2(int32_t, -9)	\
>    RUN2(uint32_t, 10)	\
>    RUN2(int64_t, -11)	\
> - RUN2(uint64_t, 12)
> + RUN2(uint64_t, 12)	\
> + RUN2(float, -11)	\
> + RUN2(double, 12)	\
>   
>   int main ()
>   {
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
> index f2dfa04cbe4..23656389d49 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
> @@ -1,11 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmul-template.h"
>   
> -<<<<<<< HEAD
> -/* { dg-final { scan-assembler-times {\tvmul\.vv} 14 } } */
> -=======
>   /* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */
>   /* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
> ->>>>>>> 1004a8ccd52 (fix  uint8)
> +/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
> index 91377299808..9ee3c6da38b 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
> @@ -1,11 +1,8 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vmul-template.h"
>   
> -<<<<<<< HEAD
> -/* { dg-final { scan-assembler-times {\tvmul\.vv} 14 } } */
> -=======
>   /* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */
>   /* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
> ->>>>>>> 1004a8ccd52 (fix  uint8)
> +/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
> index 33f9d87e1bb..4b81f52b065 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
> @@ -25,6 +25,9 @@
>    TEST_TYPE(uint32_t)	\
>    TEST_TYPE(int64_t)	\
>    TEST_TYPE(uint64_t)    \
> + TEST_TYPE(_Float16)	\
> + TEST_TYPE(float)	\
> + TEST_TYPE(double)	\
>    TEST2_TYPE(int8_t)	\
>    TEST2_TYPE(uint8_t)	\
>    TEST2_TYPE(int16_t)	\
> @@ -32,6 +35,9 @@
>    TEST2_TYPE(int32_t)	\
>    TEST2_TYPE(uint32_t)	\
>    TEST2_TYPE(int64_t)	\
> - TEST2_TYPE(uint64_t)
> + TEST2_TYPE(uint64_t)	\
> + TEST2_TYPE(_Float16)	\
> + TEST2_TYPE(float)	\
> + TEST2_TYPE(double)	\
>   
>   TEST_ALL()
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
> new file mode 100644
> index 00000000000..8f7c9c2848a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
> @@ -0,0 +1,37 @@
> +/* { dg-do run { target { riscv_zvfh_hw } } } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
> +
> +#include "vmul-template.h"
> +
> +#include <assert.h>
> +
> +#define SZ 512
> +
> +#define RUN(TYPE,VAL)				\
> +  TYPE a##TYPE[SZ];				\
> +  TYPE b##TYPE[SZ];	  			\
> +  for (int i = 0; i < SZ; i++)			\
> +  {                             		\
> +    a##TYPE[i] = 2;				\
> +    b##TYPE[i] = VAL;           		\
> +  }                             		\
> +  vadd_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (a##TYPE[i] == 2 * VAL);
> +
> +#define RUN2(TYPE,VAL)				\
> +  TYPE as##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as##TYPE[i] = 3;            		\
> +  vadds_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as##TYPE[i] == 3 * VAL);
> +
> +#define RUN_ALL()	\
> + RUN(_Float16, 4)	\
> + RUN2(_Float16, 10)	\
> +
> +int main ()
> +{
> +  RUN_ALL()
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
> index 7d2b478e1de..c6fe79e37b8 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
> @@ -1,5 +1,4 @@
> -/* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vrem-template.h"
>   
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
> index a27b9de8862..90030c80316 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
> @@ -1,5 +1,5 @@
>   /* { dg-do run { target { riscv_vector_hw } } } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vsub-template.h"
>   
> @@ -52,6 +52,8 @@
>    RUN(uint32_t, 4)	\
>    RUN(int64_t, 5)	\
>    RUN(uint64_t, 6)	\
> + RUN(float, 5)		\
> + RUN(double, 6)		\
>    RUN2(int8_t, 7)	\
>    RUN2(uint8_t, 8)	\
>    RUN2(int16_t, 7)	\
> @@ -60,6 +62,8 @@
>    RUN2(uint32_t, 10)	\
>    RUN2(int64_t, 11)	\
>    RUN2(uint64_t, 12)	\
> + RUN2(float, 11)	\
> + RUN2(double, 12)	\
>    RUN3(int8_t)		\
>    RUN3(uint8_t)		\
>    RUN3(int16_t)		\
> @@ -68,6 +72,8 @@
>    RUN3(uint32_t)		\
>    RUN3(int64_t)		\
>    RUN3(uint64_t)		\
> + RUN3(float)		\
> + RUN3(double)		\
>    RUN4(int8_t)		\
>    RUN4(uint8_t)		\
>    RUN4(int16_t)		\
> @@ -75,7 +81,9 @@
>    RUN4(int32_t)		\
>    RUN4(uint32_t)		\
>    RUN4(int64_t)		\
> - RUN4(uint64_t)
> + RUN4(uint64_t)		\
> + RUN4(float)		\
> + RUN4(double)		\
>   
>   int main ()
>   {
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
> index 5641432410e..f09d0664660 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
> @@ -1,7 +1,13 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vsub-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */
>   /* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */
> +
> +/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */
> +
> +/* Do not expect vfrsub for now, because we do not properly
> +   handle vop.vx and vfop.vf yet.  */
> +/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
> index 4fe0969c3a0..9f44f5fb5ab 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
> @@ -1,7 +1,13 @@
>   /* { dg-do compile } */
> -/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
>   
>   #include "vsub-template.h"
>   
>   /* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */
>   /* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */
> +
> +/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */
> +
> +/* Do not expect vfrsub for now, because we do not properly
> +   handle vop.vx and vfop.vf yet.  */
> +/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
> index 222972d4752..d54b7ea6aa1 100644
> --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
> @@ -41,8 +41,11 @@
>    TEST_TYPE(uint32_t)	\
>    TEST_TYPE(int64_t)	\
>    TEST_TYPE(uint64_t)    \
> - TEST2_TYPE(int8_t)	\
> + TEST_TYPE(_Float16)	\
> + TEST_TYPE(float)	\
> + TEST_TYPE(double)	\
>   
> + TEST2_TYPE(int8_t)	\
>    TEST2_TYPE(uint8_t)	\
>    TEST2_TYPE(int16_t)	\
>    TEST2_TYPE(uint16_t)	\
> @@ -50,6 +53,9 @@
>    TEST2_TYPE(uint32_t)	\
>    TEST2_TYPE(int64_t)	\
>    TEST2_TYPE(uint64_t)
> + TEST2_TYPE(_Float16)	\
> + TEST2_TYPE(float)	\
> + TEST2_TYPE(double)	\
>   
>    TEST3_TYPE(int8_t)	\
>    TEST3_TYPE(uint8_t)	\
> @@ -59,6 +65,9 @@
>    TEST3_TYPE(uint32_t)	\
>    TEST3_TYPE(int64_t)	\
>    TEST3_TYPE(uint64_t)	\
> + TEST3_TYPE(_Float16)	\
> + TEST3_TYPE(float)	\
> + TEST3_TYPE(double)	\
>   
>    TEST4_TYPE(int8_t)	\
>    TEST4_TYPE(uint8_t)	\
> @@ -67,6 +76,9 @@
>    TEST4_TYPE(int32_t)	\
>    TEST4_TYPE(uint32_t)	\
>    TEST4_TYPE(int64_t)	\
> - TEST4_TYPE(uint64_t)
> + TEST4_TYPE(uint64_t)	\
> + TEST4_TYPE(_Float16)	\
> + TEST4_TYPE(float)	\
> + TEST4_TYPE(double)	\
>   
>   TEST_ALL()
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
> new file mode 100644
> index 00000000000..262c938a0a3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
> @@ -0,0 +1,55 @@
> +/* { dg-do run { target { riscv_zvfh_hw } } } */
> +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
> +
> +#include "vsub-template.h"
> +
> +#include <assert.h>
> +
> +#define SZ 512
> +
> +#define RUN(TYPE,VAL)				\
> +  TYPE a##TYPE[SZ];				\
> +  TYPE b##TYPE[SZ];	  			\
> +  for (int i = 0; i < SZ; i++)			\
> +  {                             		\
> +    a##TYPE[i] = 999;           		\
> +    b##TYPE[i] = VAL;           		\
> +  }                             		\
> +  vsub_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (a##TYPE[i] == 999 - VAL);
> +
> +#define RUN2(TYPE,VAL)				\
> +  TYPE as##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as##TYPE[i] = 999;            		\
> +  vsubs_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as##TYPE[i] == 999 - VAL);
> +
> +#define RUN3(TYPE)				\
> +  TYPE as2##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as2##TYPE[i] = i * 33 - 779;            	\
> +  vsubi_##TYPE (as2##TYPE, as2##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as2##TYPE[i] == (TYPE)(-16 - (i * 33 - 779)));
> +
> +#define RUN4(TYPE)				\
> +  TYPE as3##TYPE[SZ];				\
> +  for (int i = 0; i < SZ; i++)			\
> +    as3##TYPE[i] = i * -17 + 667;            	\
> +  vsubi2_##TYPE (as3##TYPE, as3##TYPE, SZ);	\
> +  for (int i = 0; i < SZ; i++)			\
> +    assert (as3##TYPE[i] == (TYPE)(15 - (i * -17 + 667)));
> +
> +#define RUN_ALL()	\
> + RUN(_Float16, 4)	\
> + RUN2(_Float16, 10)	\
> + RUN3(_Float16)		\
> + RUN4(_Float16)		\
> +
> +int main ()
> +{
> +  RUN_ALL()
> +}
  
钟居哲 June 16, 2023, 6:58 a.m. UTC | #2
Currently we have 2 rounding mode enum:
/* Rounding mode bitfield for fixed point VXRM.  */
enum vxrm_field_enum
{
  VXRM_RNU,
  VXRM_RNE,
  VXRM_RDN,
  VXRM_ROD
};
/* Rounding mode bitfield for floating point FRM.  The value of enum comes
   from the below link.
   https://github.com/riscv/riscv-isa-manual/blob/main/src/f-st-ext.adoc#floating-point-control-and-status-register
 */
enum frm_field_enum
{
  FRM_RNE = 0, /* Aka 0b000.  */
  FRM_RTZ = 1, /* Aka 0b001.  */
  FRM_RDN = 2, /* Aka 0b010.  */
  FRM_RUP = 3, /* Aka 0b011.  */
  FRM_RMM = 4, /* Aka 0b100.  */
  FRM_DYN = 7, /* Aka 0b111.  */
};


But you only change frm_field_enum
into rounding_mode. It makes these 2 rounding mode odd.

I suggest you change bothe of them into fixed_point_rounding_mode and floating_point_rounding_mode.



juzhe.zhong@rivai.ai
 
From: Robin Dapp
Date: 2023-06-15 23:10
To: gcc-patches; palmer; Kito Cheng; juzhe.zhong@rivai.ai; jeffreyalaw
CC: rdapp.gcc
Subject: [PATCH v2] RISC-V: Add autovec FP binary operations.
Hi,
 
changes from V1:
- Add VF_AUTO iterator and use it.
- Ensured we don't ICE with -march=rv64gcv_zfhmin.
 
this implements the floating-point autovec expanders for binary
operations: vfadd, vfsub, vfdiv, vfmul, vfmax, vfmin and adds
tests.
 
The existing tests are split up into non-_Float16 and _Float16
flavors as we cannot rely on the zvfh extension being present.
 
As long as we do not have full middle-end support we need
-ffast-math for the tests.
 
gcc/ChangeLog:
 
* config/riscv/autovec.md (<optab><mode>3): Implement binop
expander.
* config/riscv/riscv-protos.h (emit_vlmax_fp_insn): Declare.
(emit_vlmax_fp_minmax_insn): Declare.
(enum frm_field_enum): Rename this...
(enum rounding_mode): ...to this.
* config/riscv/riscv-v.cc (emit_vlmax_fp_insn): New function
(emit_vlmax_fp_minmax_insn): New function.
* config/riscv/riscv.cc (riscv_const_insns): Clarify const
vector handling.
(riscv_libgcc_floating_mode_supported_p): Adjust comment.
(riscv_excess_precision): Do not convert to float for ZVFH.
* config/riscv/vector-iterators.md: Add VF_AUTO iterator.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/autovec/binop/vadd-run.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vadd-template.h: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vdiv-run.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vdiv-template.h: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmax-run.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmax-template.h: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmin-run.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmin-template.h: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmul-run.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vmul-template.h: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vsub-run.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vsub-template.h: Add FP.
* gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c: New test.
* gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c: New test.
* gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c: New test.
* gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c: New test.
* gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c: New test.
* gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c: New test.
---
gcc/config/riscv/autovec.md                   | 36 +++++++++
gcc/config/riscv/riscv-protos.h               |  5 +-
gcc/config/riscv/riscv-v.cc                   | 74 ++++++++++++++++++-
gcc/config/riscv/riscv.cc                     | 27 +++++--
gcc/config/riscv/vector-iterators.md          | 28 +++++++
.../riscv/rvv/autovec/binop/vadd-run.c        | 12 ++-
.../riscv/rvv/autovec/binop/vadd-rv32gcv.c    |  3 +-
.../riscv/rvv/autovec/binop/vadd-rv64gcv.c    |  3 +-
.../riscv/rvv/autovec/binop/vadd-template.h   | 11 ++-
.../riscv/rvv/autovec/binop/vadd-zvfh-run.c   | 54 ++++++++++++++
.../riscv/rvv/autovec/binop/vdiv-run.c        |  8 +-
.../riscv/rvv/autovec/binop/vdiv-rv32gcv.c    |  7 +-
.../riscv/rvv/autovec/binop/vdiv-rv64gcv.c    |  7 +-
.../riscv/rvv/autovec/binop/vdiv-template.h   |  8 +-
.../riscv/rvv/autovec/binop/vdiv-zvfh-run.c   | 37 ++++++++++
.../riscv/rvv/autovec/binop/vmax-run.c        |  9 ++-
.../riscv/rvv/autovec/binop/vmax-rv32gcv.c    |  3 +-
.../riscv/rvv/autovec/binop/vmax-rv64gcv.c    |  3 +-
.../riscv/rvv/autovec/binop/vmax-template.h   |  8 +-
.../riscv/rvv/autovec/binop/vmax-zvfh-run.c   | 38 ++++++++++
.../riscv/rvv/autovec/binop/vmin-run.c        | 10 ++-
.../riscv/rvv/autovec/binop/vmin-rv32gcv.c    |  3 +-
.../riscv/rvv/autovec/binop/vmin-rv64gcv.c    |  3 +-
.../riscv/rvv/autovec/binop/vmin-template.h   |  8 +-
.../riscv/rvv/autovec/binop/vmin-zvfh-run.c   | 37 ++++++++++
.../riscv/rvv/autovec/binop/vmul-run.c        |  8 +-
.../riscv/rvv/autovec/binop/vmul-rv32gcv.c    |  7 +-
.../riscv/rvv/autovec/binop/vmul-rv64gcv.c    |  7 +-
.../riscv/rvv/autovec/binop/vmul-template.h   |  8 +-
.../riscv/rvv/autovec/binop/vmul-zvfh-run.c   | 37 ++++++++++
.../riscv/rvv/autovec/binop/vrem-rv32gcv.c    |  3 +-
.../riscv/rvv/autovec/binop/vsub-run.c        | 12 ++-
.../riscv/rvv/autovec/binop/vsub-rv32gcv.c    |  8 +-
.../riscv/rvv/autovec/binop/vsub-rv64gcv.c    |  8 +-
.../riscv/rvv/autovec/binop/vsub-template.h   | 16 +++-
.../riscv/rvv/autovec/binop/vsub-zvfh-run.c   | 55 ++++++++++++++
36 files changed, 555 insertions(+), 56 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
 
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 579cbb07234..94452c932a4 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -769,3 +769,39 @@ (define_expand "vec_init<vi_half><mode>"
{
   DONE;
})
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Binary operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfadd.vv/vfsub.vv/...
+;; - vfadd.vf/vfsub.vf/...
+;; -------------------------------------------------------------------------
+(define_expand "<optab><mode>3"
+  [(match_operand:VF_AUTO 0 "register_operand")
+   (any_float_binop:VF_AUTO
+    (match_operand:VF_AUTO 1 "register_operand")
+    (match_operand:VF_AUTO 2 "register_operand"))]
+  "TARGET_VECTOR"
+{
+  riscv_vector::emit_vlmax_fp_insn (code_for_pred (<CODE>, <MODE>mode),
+     riscv_vector::RVV_BINOP, operands);
+  DONE;
+})
+
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmin.vv/vfmax.vv
+;; - vfmin.vf/vfmax.vf
+;; -------------------------------------------------------------------------
+(define_expand "<optab><mode>3"
+  [(match_operand:VF_AUTO 0 "register_operand")
+   (any_float_binop_nofrm:VF_AUTO
+    (match_operand:VF_AUTO 1 "register_operand")
+    (match_operand:VF_AUTO 2 "register_operand"))]
+  "TARGET_VECTOR"
+{
+  riscv_vector::emit_vlmax_fp_minmax_insn (code_for_pred (<CODE>, <MODE>mode),
+    riscv_vector::RVV_BINOP, operands);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index f422adf8521..8e8f3b1f454 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -185,6 +185,8 @@ bool legitimize_move (rtx, rtx);
void emit_vlmax_vsetvl (machine_mode, rtx);
void emit_hard_vlmax_vsetvl (machine_mode, rtx);
void emit_vlmax_insn (unsigned, int, rtx *, rtx = 0);
+void emit_vlmax_fp_insn (unsigned, int, rtx *, rtx = 0);
+void emit_vlmax_fp_minmax_insn (unsigned, int, rtx *, rtx = 0);
void emit_vlmax_ternary_insn (unsigned, int, rtx *, rtx = 0);
void emit_nonvlmax_insn (unsigned, int, rtx *, rtx);
void emit_vlmax_slide_insn (unsigned, rtx *);
@@ -260,11 +262,12 @@ enum vxrm_field_enum
   VXRM_RDN,
   VXRM_ROD
};
+
/* Rounding mode bitfield for floating point FRM.  The value of enum comes
    from the below link.
    https://github.com/riscv/riscv-isa-manual/blob/main/src/f-st-ext.adoc#floating-point-control-and-status-register
  */
-enum frm_field_enum
+enum rounding_mode
{
   FRM_RNE = 0, /* Aka 0b000.  */
   FRM_RTZ = 1, /* Aka 0b001.  */
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 1c86cfbdcee..e4c6af83ffd 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -74,8 +74,10 @@ public:
     : m_opno (0), m_op_num (0), m_has_dest_p (false),
       m_fully_unmasked_p (false), m_use_real_merge_p (false),
       m_needs_avl_p (false), m_vlmax_p (false), m_has_tail_policy_p (false),
-      m_has_mask_policy_p (false), m_tail_policy (TAIL_ANY),
-      m_mask_policy (MASK_ANY), m_dest_mode (VOIDmode), m_mask_mode (VOIDmode),
+      m_has_mask_policy_p (false), m_has_fp_rounding_mode_p (false),
+      m_tail_policy (TAIL_ANY), m_mask_policy (MASK_ANY),
+      m_fp_rounding_mode (FRM_DYN),
+      m_dest_mode (VOIDmode), m_mask_mode (VOIDmode),
       m_vl_op (NULL_RTX)
   {}
@@ -87,8 +89,10 @@ public:
       m_fully_unmasked_p (use_all_trues_mask_p),
       m_use_real_merge_p (use_real_merge_p), m_needs_avl_p (needs_avl_p),
       m_vlmax_p (vlmax_p), m_has_tail_policy_p (false),
-      m_has_mask_policy_p (false), m_tail_policy (TAIL_ANY),
-      m_mask_policy (MASK_ANY), m_dest_mode (dest_mode),
+      m_has_mask_policy_p (false), m_has_fp_rounding_mode_p (false),
+      m_tail_policy (TAIL_ANY), m_mask_policy (MASK_ANY),
+      m_fp_rounding_mode (FRM_DYN),
+      m_dest_mode (dest_mode),
       m_mask_mode (mask_mode), m_vl_op (NULL_RTX)
   {}
@@ -104,6 +108,12 @@ public:
   }
   void set_vl (rtx vl) { m_vl_op = vl; }
+  void set_rounding_mode (enum rounding_mode mode)
+  {
+    m_has_fp_rounding_mode_p = true;
+    m_fp_rounding_mode = mode;
+  }
+
   void add_output_operand (rtx x, machine_mode mode)
   {
     create_output_operand (&m_ops[m_opno++], x, mode);
@@ -140,6 +150,15 @@ public:
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
+  void add_rounding_mode_operand ()
+  {
+    if (m_has_fp_rounding_mode_p)
+      {
+ rtx frm_rtx = gen_int_mode (m_fp_rounding_mode, Pmode);
+ add_input_operand (frm_rtx, Pmode);
+      }
+  }
+
   void emit_insn (enum insn_code icode, rtx *ops)
   {
     int opno = 0;
@@ -200,6 +219,9 @@ public:
       add_policy_operand ();
     if (m_needs_avl_p)
       add_avl_type_operand (m_vlmax_p ? avl_type::VLMAX : avl_type::NONVLMAX);
+
+    add_rounding_mode_operand ();
+
     expand (icode, any_mem_p);
   }
@@ -231,8 +253,10 @@ private:
   bool m_vlmax_p;
   bool m_has_tail_policy_p;
   bool m_has_mask_policy_p;
+  bool m_has_fp_rounding_mode_p;
   enum tail_policy m_tail_policy;
   enum mask_policy m_mask_policy;
+  enum rounding_mode m_fp_rounding_mode;
   machine_mode m_dest_mode;
   machine_mode m_mask_mode;
   rtx m_vl_op;
@@ -653,6 +677,48 @@ emit_vlmax_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
   e.emit_insn ((enum insn_code) icode, ops);
}
+void
+emit_vlmax_fp_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (op_num,
+   /* HAS_DEST_P */ true,
+   /* FULLY_UNMASKED_P */ true,
+   /* USE_REAL_MERGE_P */ false,
+   /* HAS_AVL_P */ true,
+   /* VLMAX_P */ true,
+   dest_mode,
+   mask_mode);
+
+  e.set_policy (TAIL_ANY);
+  e.set_policy (MASK_ANY);
+  e.set_rounding_mode (FRM_DYN);
+  e.set_vl (vl);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
+void
+emit_vlmax_fp_minmax_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (op_num,
+   /* HAS_DEST_P */ true,
+   /* FULLY_UNMASKED_P */ true,
+   /* USE_REAL_MERGE_P */ false,
+   /* HAS_AVL_P */ true,
+   /* VLMAX_P */ true,
+   dest_mode,
+   mask_mode);
+
+  e.set_policy (TAIL_ANY);
+  e.set_policy (MASK_ANY);
+
+  e.set_vl (vl);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
/* This function emits a {VLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
  * ternary operation which always has a real merge operand.  */
void
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index e5ae4e81b7a..c4588a55e04 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1306,11 +1306,22 @@ riscv_const_insns (rtx x)
if (satisfies_constraint_vi (x))
  return 1;
- /* A const duplicate vector can always be broadcast from
-    a general-purpose register.  This means we need as many
-    insns as it takes to load the constant into the GPR
-    and one vmv.v.x.  */
- return 1 + riscv_const_insns (elt);
+ /* Any int/FP constants can always be broadcast from a
+    scalar register.  Loading of a floating-point
+    constant incurs a literal-pool access.  Allow this in
+    order to increase vectorization possibilities.  */
+ int n = riscv_const_insns (elt);
+ if (CONST_DOUBLE_P (elt))
+     return 1 + 4; /* vfmv.v.f + memory access.  */
+ else
+   {
+     /* We need as many insns as it takes to load the constant
+        into a GPR and one vmv.v.x.  */
+     if (n != 0)
+       return 1 + n;
+     else
+       return 1 + 4; /*vmv.v.x + memory access.  */
+   }
      }
  }
@@ -7209,8 +7220,8 @@ riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode)
        precision of the _FloatN type; evaluate all other operations and
        constants to the range and precision of the semantic type;
-   If we have the zfh/zhinx extensions then we support _Float16 in native
-   precision, so we should set this to 16.  */
+   If we have the zfh/zhinx/zvfh extensions then we support _Float16
+   in native precision, so we should set this to 16.  */
static enum flt_eval_method
riscv_excess_precision (enum excess_precision_type type)
{
@@ -7218,7 +7229,7 @@ riscv_excess_precision (enum excess_precision_type type)
     {
     case EXCESS_PRECISION_TYPE_FAST:
     case EXCESS_PRECISION_TYPE_STANDARD:
-      return ((TARGET_ZFH || TARGET_ZHINX)
+      return ((TARGET_ZFH || TARGET_ZHINX || TARGET_ZVFH)
? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
     case EXCESS_PRECISION_TYPE_IMPLICIT:
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 139d2b74d7c..e6040c1981c 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -317,6 +317,34 @@ (define_mode_iterator VF [
   (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
])
+;; This iterator is the same as above but with TARGET_VECTOR_ELEN_FP_16
+;; changed to TARGET_ZVFH.  TARGET_VECTOR_ELEN_FP_16 is also true for
+;; TARGET_ZVFHMIN while we actually disable all instructions apart from
+;; load, store and convert for it.
+;; Consequently the autovec expanders should also only be enabled with
+;; TARGET_ZVFH.
+(define_mode_iterator VF_AUTO [
+  (VNx1HF "TARGET_ZVFH && TARGET_MIN_VLEN < 128")
+  (VNx2HF "TARGET_ZVFH")
+  (VNx4HF "TARGET_ZVFH")
+  (VNx8HF "TARGET_ZVFH")
+  (VNx16HF "TARGET_ZVFH")
+  (VNx32HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
+  (VNx64HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
+
+  (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128")
+  (VNx2SF "TARGET_VECTOR_ELEN_FP_32")
+  (VNx4SF "TARGET_VECTOR_ELEN_FP_32")
+  (VNx8SF "TARGET_VECTOR_ELEN_FP_32")
+  (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
+  (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128")
+  (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128")
+  (VNx2DF "TARGET_VECTOR_ELEN_FP_64")
+  (VNx4DF "TARGET_VECTOR_ELEN_FP_64")
+  (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
+  (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
+])
+
(define_mode_iterator VI_HAS_HALF [
    VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
    (VNx32SI "TARGET_MIN_VLEN >= 128")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
index 65f61b0e932..7f05e589172 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
@@ -51,7 +51,9 @@
  RUN(int32_t, -3) \
  RUN(uint32_t, 4) \
  RUN(int64_t, -5) \
- RUN(uint64_t, 6)    \
+ RUN(uint64_t, 6) \
+ RUN(float, -5) \
+ RUN(double, 6) \
  RUN2(int8_t, -7) \
  RUN2(uint8_t, 8) \
  RUN2(int16_t, -7) \
@@ -59,7 +61,9 @@
  RUN2(int32_t, -9) \
  RUN2(uint32_t, 10) \
  RUN2(int64_t, -11) \
- RUN2(uint64_t, 12)   \
+ RUN2(uint64_t, 12) \
+ RUN2(float, -11) \
+ RUN2(double, 12) \
  RUN3M(int8_t, 13) \
  RUN3(uint8_t, 14) \
  RUN3M(int16_t, 13) \
@@ -67,7 +71,9 @@
  RUN3M(int32_t, 15) \
  RUN3(uint32_t, 16) \
  RUN3M(int64_t, 17) \
- RUN3(uint64_t, 18)
+ RUN3(uint64_t, 18) \
+ RUN3(float, 17) \
+ RUN3M(double, 18) \
int main ()
{
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
index 2d094749c6a..cd0da74d8a5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vadd-template.h"
/* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */
/* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfadd\.vv} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
index 4a1dc41c34a..30c3ef7bd4f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vadd-template.h"
/* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */
/* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfadd\.vv} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
index fecf2947691..e05b9c76275 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
@@ -41,6 +41,9 @@
  TEST_TYPE(uint32_t) \
  TEST_TYPE(int64_t) \
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16) \
+ TEST_TYPE(float) \
+ TEST_TYPE(double) \
  TEST2_TYPE(int8_t) \
  TEST2_TYPE(uint8_t) \
  TEST2_TYPE(int16_t) \
@@ -49,6 +52,9 @@
  TEST2_TYPE(uint32_t) \
  TEST2_TYPE(int64_t) \
  TEST2_TYPE(uint64_t)   \
+ TEST2_TYPE(_Float16) \
+ TEST2_TYPE(float) \
+ TEST2_TYPE(double) \
  TEST3M_TYPE(int8_t) \
  TEST3_TYPE(uint8_t) \
  TEST3M_TYPE(int16_t) \
@@ -56,6 +62,9 @@
  TEST3M_TYPE(int32_t) \
  TEST3_TYPE(uint32_t) \
  TEST3M_TYPE(int64_t) \
- TEST3_TYPE(uint64_t)
+ TEST3_TYPE(uint64_t)   \
+ TEST3M_TYPE(_Float16) \
+ TEST3_TYPE(float) \
+ TEST3M_TYPE(double) \
TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
new file mode 100644
index 00000000000..595a5337939
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
@@ -0,0 +1,54 @@
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vadd-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL) \
+  TYPE a##TYPE[SZ]; \
+  TYPE b##TYPE[SZ];   \
+  for (int i = 0; i < SZ; i++) \
+  {                             \
+    a##TYPE[i] = 0;             \
+    b##TYPE[i] = VAL;           \
+  }                             \
+  vadd_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (a##TYPE[i] == VAL);
+
+#define RUN2(TYPE,VAL) \
+  TYPE as##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as##TYPE[i] = 0;            \
+  vadds_##TYPE (as##TYPE, as##TYPE, VAL, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as##TYPE[i] == VAL);
+
+#define RUN3(TYPE,VAL) \
+  TYPE ai##TYPE[SZ];           \
+  for (int i = 0; i < SZ; i++) \
+    ai##TYPE[i] = VAL; \
+  vaddi_##TYPE (ai##TYPE, ai##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (ai##TYPE[i] == VAL + 15);
+
+#define RUN3M(TYPE,VAL) \
+  TYPE aim##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    aim##TYPE[i] = VAL; \
+  vaddim_##TYPE (aim##TYPE, aim##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (aim##TYPE[i] == VAL - 16);
+
+#define RUN_ALL() \
+ RUN(_Float16, 4) \
+ RUN2(_Float16, 10) \
+ RUN3M(_Float16, 17) \
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
index 810757a8834..9960c399b1f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vdiv-template.h"
@@ -36,6 +36,8 @@
  RUN(uint32_t, 4) \
  RUN(int64_t, -5) \
  RUN(uint64_t, 6) \
+ RUN(float, -5) \
+ RUN(double, 6) \
  RUN2(int8_t, -7) \
  RUN2(uint8_t, 8) \
  RUN2(int16_t, -7) \
@@ -43,7 +45,9 @@
  RUN2(int32_t, -9) \
  RUN2(uint32_t, 10) \
  RUN2(int64_t, -11) \
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12) \
+ RUN2(float, -11) \
+ RUN2(double, 12) \
int main ()
{
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
index 9f059ebc84c..604d9acb038 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vdiv-template.h"
@@ -8,3 +8,8 @@
/* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */
/* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */
+
+/* Division by constant is done by calculating a reciprocal and
+   then multiplying.  Hence we do not expect 6 vfdivs.  */
+/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
index cd5d30b8974..26884035d57 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vdiv-template.h"
@@ -8,3 +8,8 @@
/* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */
/* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */
+
+/* Division by constant is done by calculating a reciprocal and
+   then multiplying.  Hence we do not expect 6 vfdivs.  */
+/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
index fd9199722b6..7b0f579d1c9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
@@ -25,6 +25,9 @@
  TEST_TYPE(uint32_t) \
  TEST_TYPE(int64_t) \
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16) \
+ TEST_TYPE(float) \
+ TEST_TYPE(double) \
  TEST2_TYPE(int8_t) \
  TEST2_TYPE(uint8_t) \
  TEST2_TYPE(int16_t) \
@@ -32,6 +35,9 @@
  TEST2_TYPE(int32_t) \
  TEST2_TYPE(uint32_t) \
  TEST2_TYPE(int64_t) \
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t) \
+ TEST2_TYPE(_Float16) \
+ TEST2_TYPE(float) \
+ TEST2_TYPE(double) \
TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
new file mode 100644
index 00000000000..c1c84e87a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
@@ -0,0 +1,37 @@
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vdiv-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL) \
+  TYPE a##TYPE[SZ]; \
+  TYPE b##TYPE[SZ];   \
+  for (int i = 0; i < SZ; i++) \
+  {                             \
+    a##TYPE[i] = VAL * 3;       \
+    b##TYPE[i] = VAL;           \
+  }                             \
+  vdiv_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (a##TYPE[i] == 3);
+
+#define RUN2(TYPE,VAL) \
+  TYPE as##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as##TYPE[i] = VAL * 5; \
+  vdivs_##TYPE (as##TYPE, as##TYPE, VAL, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as##TYPE[i] == 5);
+
+#define RUN_ALL() \
+ RUN(_Float16, 4) \
+ RUN2(_Float16, 10) \
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
index d889f28b298..da90fe8da33 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmax-template.h"
@@ -27,6 +27,7 @@
   for (int i = 0; i < SZ; i++) \
     assert (as##TYPE[i] == 0 > VAL ? 0 : VAL);
+
#define RUN_ALL() \
  RUN(int8_t, -1) \
  RUN(uint8_t, 2) \
@@ -36,6 +37,8 @@
  RUN(uint32_t, 4) \
  RUN(int64_t, -5) \
  RUN(uint64_t, 6) \
+ RUN(float, -5) \
+ RUN(double, 6) \
  RUN2(int8_t, -7) \
  RUN2(uint8_t, 8) \
  RUN2(int16_t, -7) \
@@ -43,7 +46,9 @@
  RUN2(int32_t, -9) \
  RUN2(uint32_t, 10) \
  RUN2(int64_t, -11) \
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12) \
+ RUN2(float, -11) \
+ RUN2(double, 12) \
int main ()
{
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
index 7b217d990a6..fbfa3ab057d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmax-template.h"
/* { dg-final { scan-assembler-times {\tvmax\.vv} 8 } } */
/* { dg-final { scan-assembler-times {\tvmaxu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmax\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
index 1b7f8c6be16..cf01ebc65f8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmax-template.h"
/* { dg-final { scan-assembler-times {\tvmax\.vv} 8 } } */
/* { dg-final { scan-assembler-times {\tvmaxu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmax\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
index 6deb5126c7d..54828cd922a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
@@ -25,6 +25,9 @@
  TEST_TYPE(uint32_t) \
  TEST_TYPE(int64_t) \
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16) \
+ TEST_TYPE(float) \
+ TEST_TYPE(double) \
  TEST2_TYPE(int8_t) \
  TEST2_TYPE(uint8_t) \
  TEST2_TYPE(int16_t) \
@@ -32,6 +35,9 @@
  TEST2_TYPE(int32_t) \
  TEST2_TYPE(uint32_t) \
  TEST2_TYPE(int64_t) \
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t) \
+ TEST2_TYPE(_Float16) \
+ TEST2_TYPE(float) \
+ TEST2_TYPE(double) \
TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
new file mode 100644
index 00000000000..1ab3d5d1199
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
@@ -0,0 +1,38 @@
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vmax-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL) \
+  TYPE a##TYPE[SZ]; \
+  TYPE b##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+  {                             \
+    a##TYPE[i] = 0;             \
+    b##TYPE[i] = VAL;           \
+  }                             \
+  vmax_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (a##TYPE[i] == 0 > VAL ? 0 : VAL);
+
+#define RUN2(TYPE,VAL) \
+  TYPE as##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as##TYPE[i] = 0; \
+  vmaxs_##TYPE (as##TYPE, as##TYPE, VAL, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as##TYPE[i] == 0 > VAL ? 0 : VAL);
+
+
+#define RUN_ALL() \
+ RUN(_Float16, 4) \
+ RUN2(_Float16, 10) \
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
index a5887e6097f..e8ac9395d7b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmin-template.h"
@@ -35,7 +35,9 @@
  RUN(int32_t, -3) \
  RUN(uint32_t, 4) \
  RUN(int64_t, -5) \
- RUN(uint64_t, 6)    \
+ RUN(uint64_t, 6) \
+ RUN(float, -5) \
+ RUN(double, 6) \
  RUN2(int8_t, -7) \
  RUN2(uint8_t, 8) \
  RUN2(int16_t, -7) \
@@ -43,7 +45,9 @@
  RUN2(int32_t, -9) \
  RUN2(uint32_t, 10) \
  RUN2(int64_t, -11) \
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12) \
+ RUN2(float, -11) \
+ RUN2(double, 12) \
int main ()
{
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
index bf826ebf53a..87640732b3b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmin-template.h"
/* { dg-final { scan-assembler-times {\tvmin\.vv} 8 } } */
/* { dg-final { scan-assembler-times {\tvminu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmin\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
index f57d4369006..193dacc82c5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmin-template.h"
/* { dg-final { scan-assembler-times {\tvmin\.vv} 8 } } */
/* { dg-final { scan-assembler-times {\tvminu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmin\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
index 1225d5aca64..ca0d4e751e3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
@@ -25,6 +25,9 @@
  TEST_TYPE(uint32_t) \
  TEST_TYPE(int64_t) \
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16) \
+ TEST_TYPE(float) \
+ TEST_TYPE(double) \
  TEST2_TYPE(int8_t) \
  TEST2_TYPE(uint8_t) \
  TEST2_TYPE(int16_t) \
@@ -32,6 +35,9 @@
  TEST2_TYPE(int32_t) \
  TEST2_TYPE(uint32_t) \
  TEST2_TYPE(int64_t) \
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t) \
+ TEST2_TYPE(_Float16) \
+ TEST2_TYPE(float) \
+ TEST2_TYPE(double) \
TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
new file mode 100644
index 00000000000..2d593542f0e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
@@ -0,0 +1,37 @@
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vmin-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL) \
+  TYPE a##TYPE[SZ]; \
+  TYPE b##TYPE[SZ];   \
+  for (int i = 0; i < SZ; i++) \
+  {                             \
+    a##TYPE[i] = 0;             \
+    b##TYPE[i] = VAL;           \
+  }                             \
+  vmin_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (a##TYPE[i] == 0 < VAL ? 0 : VAL);
+
+#define RUN2(TYPE,VAL) \
+  TYPE as##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as##TYPE[i] = 0; \
+  vmins_##TYPE (as##TYPE, as##TYPE, VAL, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as##TYPE[i] == 0 < VAL ? 0 : VAL);
+
+#define RUN_ALL() \
+ RUN(_Float16, 4) \
+ RUN2(_Float16, 10) \
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
index 22a2c1a18bb..60d0c906107 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmul-template.h"
@@ -36,6 +36,8 @@
  RUN(uint32_t, 4) \
  RUN(int64_t, -5) \
  RUN(uint64_t, 6) \
+ RUN(float, -5) \
+ RUN(double, 6) \
  RUN2(int8_t, -7) \
  RUN2(uint8_t, 8) \
  RUN2(int16_t, -7) \
@@ -43,7 +45,9 @@
  RUN2(int32_t, -9) \
  RUN2(uint32_t, 10) \
  RUN2(int64_t, -11) \
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12) \
+ RUN2(float, -11) \
+ RUN2(double, 12) \
int main ()
{
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
index f2dfa04cbe4..23656389d49 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
@@ -1,11 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmul-template.h"
-<<<<<<< HEAD
-/* { dg-final { scan-assembler-times {\tvmul\.vv} 14 } } */
-=======
/* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */
/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
->>>>>>> 1004a8ccd52 (fix  uint8)
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
index 91377299808..9ee3c6da38b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
@@ -1,11 +1,8 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vmul-template.h"
-<<<<<<< HEAD
-/* { dg-final { scan-assembler-times {\tvmul\.vv} 14 } } */
-=======
/* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */
/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
->>>>>>> 1004a8ccd52 (fix  uint8)
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
index 33f9d87e1bb..4b81f52b065 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
@@ -25,6 +25,9 @@
  TEST_TYPE(uint32_t) \
  TEST_TYPE(int64_t) \
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16) \
+ TEST_TYPE(float) \
+ TEST_TYPE(double) \
  TEST2_TYPE(int8_t) \
  TEST2_TYPE(uint8_t) \
  TEST2_TYPE(int16_t) \
@@ -32,6 +35,9 @@
  TEST2_TYPE(int32_t) \
  TEST2_TYPE(uint32_t) \
  TEST2_TYPE(int64_t) \
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t) \
+ TEST2_TYPE(_Float16) \
+ TEST2_TYPE(float) \
+ TEST2_TYPE(double) \
TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
new file mode 100644
index 00000000000..8f7c9c2848a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
@@ -0,0 +1,37 @@
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vmul-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL) \
+  TYPE a##TYPE[SZ]; \
+  TYPE b##TYPE[SZ];   \
+  for (int i = 0; i < SZ; i++) \
+  {                             \
+    a##TYPE[i] = 2; \
+    b##TYPE[i] = VAL;           \
+  }                             \
+  vadd_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (a##TYPE[i] == 2 * VAL);
+
+#define RUN2(TYPE,VAL) \
+  TYPE as##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as##TYPE[i] = 3;            \
+  vadds_##TYPE (as##TYPE, as##TYPE, VAL, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as##TYPE[i] == 3 * VAL);
+
+#define RUN_ALL() \
+ RUN(_Float16, 4) \
+ RUN2(_Float16, 10) \
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
index 7d2b478e1de..c6fe79e37b8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
@@ -1,5 +1,4 @@
-/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vrem-template.h"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
index a27b9de8862..90030c80316 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
@@ -1,5 +1,5 @@
/* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vsub-template.h"
@@ -52,6 +52,8 @@
  RUN(uint32_t, 4) \
  RUN(int64_t, 5) \
  RUN(uint64_t, 6) \
+ RUN(float, 5) \
+ RUN(double, 6) \
  RUN2(int8_t, 7) \
  RUN2(uint8_t, 8) \
  RUN2(int16_t, 7) \
@@ -60,6 +62,8 @@
  RUN2(uint32_t, 10) \
  RUN2(int64_t, 11) \
  RUN2(uint64_t, 12) \
+ RUN2(float, 11) \
+ RUN2(double, 12) \
  RUN3(int8_t) \
  RUN3(uint8_t) \
  RUN3(int16_t) \
@@ -68,6 +72,8 @@
  RUN3(uint32_t) \
  RUN3(int64_t) \
  RUN3(uint64_t) \
+ RUN3(float) \
+ RUN3(double) \
  RUN4(int8_t) \
  RUN4(uint8_t) \
  RUN4(int16_t) \
@@ -75,7 +81,9 @@
  RUN4(int32_t) \
  RUN4(uint32_t) \
  RUN4(int64_t) \
- RUN4(uint64_t)
+ RUN4(uint64_t) \
+ RUN4(float) \
+ RUN4(double) \
int main ()
{
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
index 5641432410e..f09d0664660 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
@@ -1,7 +1,13 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vsub-template.h"
/* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */
/* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */
+
+/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */
+
+/* Do not expect vfrsub for now, because we do not properly
+   handle vop.vx and vfop.vf yet.  */
+/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
index 4fe0969c3a0..9f44f5fb5ab 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
@@ -1,7 +1,13 @@
/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
#include "vsub-template.h"
/* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */
/* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */
+
+/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */
+
+/* Do not expect vfrsub for now, because we do not properly
+   handle vop.vx and vfop.vf yet.  */
+/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
index 222972d4752..d54b7ea6aa1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
@@ -41,8 +41,11 @@
  TEST_TYPE(uint32_t) \
  TEST_TYPE(int64_t) \
  TEST_TYPE(uint64_t)    \
- TEST2_TYPE(int8_t) \
+ TEST_TYPE(_Float16) \
+ TEST_TYPE(float) \
+ TEST_TYPE(double) \
+ TEST2_TYPE(int8_t) \
  TEST2_TYPE(uint8_t) \
  TEST2_TYPE(int16_t) \
  TEST2_TYPE(uint16_t) \
@@ -50,6 +53,9 @@
  TEST2_TYPE(uint32_t) \
  TEST2_TYPE(int64_t) \
  TEST2_TYPE(uint64_t)
+ TEST2_TYPE(_Float16) \
+ TEST2_TYPE(float) \
+ TEST2_TYPE(double) \
  TEST3_TYPE(int8_t) \
  TEST3_TYPE(uint8_t) \
@@ -59,6 +65,9 @@
  TEST3_TYPE(uint32_t) \
  TEST3_TYPE(int64_t) \
  TEST3_TYPE(uint64_t) \
+ TEST3_TYPE(_Float16) \
+ TEST3_TYPE(float) \
+ TEST3_TYPE(double) \
  TEST4_TYPE(int8_t) \
  TEST4_TYPE(uint8_t) \
@@ -67,6 +76,9 @@
  TEST4_TYPE(int32_t) \
  TEST4_TYPE(uint32_t) \
  TEST4_TYPE(int64_t) \
- TEST4_TYPE(uint64_t)
+ TEST4_TYPE(uint64_t) \
+ TEST4_TYPE(_Float16) \
+ TEST4_TYPE(float) \
+ TEST4_TYPE(double) \
TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
new file mode 100644
index 00000000000..262c938a0a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
@@ -0,0 +1,55 @@
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vsub-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL) \
+  TYPE a##TYPE[SZ]; \
+  TYPE b##TYPE[SZ];   \
+  for (int i = 0; i < SZ; i++) \
+  {                             \
+    a##TYPE[i] = 999;           \
+    b##TYPE[i] = VAL;           \
+  }                             \
+  vsub_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (a##TYPE[i] == 999 - VAL);
+
+#define RUN2(TYPE,VAL) \
+  TYPE as##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as##TYPE[i] = 999;            \
+  vsubs_##TYPE (as##TYPE, as##TYPE, VAL, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as##TYPE[i] == 999 - VAL);
+
+#define RUN3(TYPE) \
+  TYPE as2##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as2##TYPE[i] = i * 33 - 779;            \
+  vsubi_##TYPE (as2##TYPE, as2##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as2##TYPE[i] == (TYPE)(-16 - (i * 33 - 779)));
+
+#define RUN4(TYPE) \
+  TYPE as3##TYPE[SZ]; \
+  for (int i = 0; i < SZ; i++) \
+    as3##TYPE[i] = i * -17 + 667;            \
+  vsubi2_##TYPE (as3##TYPE, as3##TYPE, SZ); \
+  for (int i = 0; i < SZ; i++) \
+    assert (as3##TYPE[i] == (TYPE)(15 - (i * -17 + 667)));
+
+#define RUN_ALL() \
+ RUN(_Float16, 4) \
+ RUN2(_Float16, 10) \
+ RUN3(_Float16) \
+ RUN4(_Float16) \
+
+int main ()
+{
+  RUN_ALL()
+}
-- 
2.40.1
  
Robin Dapp June 16, 2023, 7:31 a.m. UTC | #3
Yes, already did that and will send next version soon.

Just still looking at a lot of test failures with
-march=rv64gc_zvfhmin (note, no rv64gcv) that are
somewhat independent of this patch.

Regards
 Robin
  
Robin Dapp June 16, 2023, 12:41 p.m. UTC | #4
> Why do we need '-ffast-math' with the tests?

Normally we would use the COND_ADD to mask out possibly trapping
vector elements and the likes but COND_ADD works with normal
vector masking.  What we currently have is no masking but the
LEN_LOAD/LEN_STORE machinery i.e. length-controlled loops.
There is no LEN_MASK_COND_ADD yet, but Juzhe is working to upstream
it.  Once this is in place we don't need -ffast-math anymore.

Regards
 Robin
  

Patch

diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 579cbb07234..94452c932a4 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -769,3 +769,39 @@  (define_expand "vec_init<vi_half><mode>"
 {
   DONE;
 })
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Binary operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfadd.vv/vfsub.vv/...
+;; - vfadd.vf/vfsub.vf/...
+;; -------------------------------------------------------------------------
+(define_expand "<optab><mode>3"
+  [(match_operand:VF_AUTO 0 "register_operand")
+   (any_float_binop:VF_AUTO
+    (match_operand:VF_AUTO 1 "register_operand")
+    (match_operand:VF_AUTO 2 "register_operand"))]
+  "TARGET_VECTOR"
+{
+  riscv_vector::emit_vlmax_fp_insn (code_for_pred (<CODE>, <MODE>mode),
+				    riscv_vector::RVV_BINOP, operands);
+  DONE;
+})
+
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - vfmin.vv/vfmax.vv
+;; - vfmin.vf/vfmax.vf
+;; -------------------------------------------------------------------------
+(define_expand "<optab><mode>3"
+  [(match_operand:VF_AUTO 0 "register_operand")
+   (any_float_binop_nofrm:VF_AUTO
+    (match_operand:VF_AUTO 1 "register_operand")
+    (match_operand:VF_AUTO 2 "register_operand"))]
+  "TARGET_VECTOR"
+{
+  riscv_vector::emit_vlmax_fp_minmax_insn (code_for_pred (<CODE>, <MODE>mode),
+					   riscv_vector::RVV_BINOP, operands);
+  DONE;
+})
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index f422adf8521..8e8f3b1f454 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -185,6 +185,8 @@  bool legitimize_move (rtx, rtx);
 void emit_vlmax_vsetvl (machine_mode, rtx);
 void emit_hard_vlmax_vsetvl (machine_mode, rtx);
 void emit_vlmax_insn (unsigned, int, rtx *, rtx = 0);
+void emit_vlmax_fp_insn (unsigned, int, rtx *, rtx = 0);
+void emit_vlmax_fp_minmax_insn (unsigned, int, rtx *, rtx = 0);
 void emit_vlmax_ternary_insn (unsigned, int, rtx *, rtx = 0);
 void emit_nonvlmax_insn (unsigned, int, rtx *, rtx);
 void emit_vlmax_slide_insn (unsigned, rtx *);
@@ -260,11 +262,12 @@  enum vxrm_field_enum
   VXRM_RDN,
   VXRM_ROD
 };
+
 /* Rounding mode bitfield for floating point FRM.  The value of enum comes
    from the below link.
    https://github.com/riscv/riscv-isa-manual/blob/main/src/f-st-ext.adoc#floating-point-control-and-status-register
  */
-enum frm_field_enum
+enum rounding_mode
 {
   FRM_RNE = 0, /* Aka 0b000.  */
   FRM_RTZ = 1, /* Aka 0b001.  */
diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc
index 1c86cfbdcee..e4c6af83ffd 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -74,8 +74,10 @@  public:
     : m_opno (0), m_op_num (0), m_has_dest_p (false),
       m_fully_unmasked_p (false), m_use_real_merge_p (false),
       m_needs_avl_p (false), m_vlmax_p (false), m_has_tail_policy_p (false),
-      m_has_mask_policy_p (false), m_tail_policy (TAIL_ANY),
-      m_mask_policy (MASK_ANY), m_dest_mode (VOIDmode), m_mask_mode (VOIDmode),
+      m_has_mask_policy_p (false), m_has_fp_rounding_mode_p (false),
+      m_tail_policy (TAIL_ANY), m_mask_policy (MASK_ANY),
+      m_fp_rounding_mode (FRM_DYN),
+      m_dest_mode (VOIDmode), m_mask_mode (VOIDmode),
       m_vl_op (NULL_RTX)
   {}
 
@@ -87,8 +89,10 @@  public:
       m_fully_unmasked_p (use_all_trues_mask_p),
       m_use_real_merge_p (use_real_merge_p), m_needs_avl_p (needs_avl_p),
       m_vlmax_p (vlmax_p), m_has_tail_policy_p (false),
-      m_has_mask_policy_p (false), m_tail_policy (TAIL_ANY),
-      m_mask_policy (MASK_ANY), m_dest_mode (dest_mode),
+      m_has_mask_policy_p (false), m_has_fp_rounding_mode_p (false),
+      m_tail_policy (TAIL_ANY), m_mask_policy (MASK_ANY),
+      m_fp_rounding_mode (FRM_DYN),
+      m_dest_mode (dest_mode),
       m_mask_mode (mask_mode), m_vl_op (NULL_RTX)
   {}
 
@@ -104,6 +108,12 @@  public:
   }
   void set_vl (rtx vl) { m_vl_op = vl; }
 
+  void set_rounding_mode (enum rounding_mode mode)
+  {
+    m_has_fp_rounding_mode_p = true;
+    m_fp_rounding_mode = mode;
+  }
+
   void add_output_operand (rtx x, machine_mode mode)
   {
     create_output_operand (&m_ops[m_opno++], x, mode);
@@ -140,6 +150,15 @@  public:
     add_input_operand (gen_int_mode (type, Pmode), Pmode);
   }
 
+  void add_rounding_mode_operand ()
+  {
+    if (m_has_fp_rounding_mode_p)
+      {
+	rtx frm_rtx = gen_int_mode (m_fp_rounding_mode, Pmode);
+	add_input_operand (frm_rtx, Pmode);
+      }
+  }
+
   void emit_insn (enum insn_code icode, rtx *ops)
   {
     int opno = 0;
@@ -200,6 +219,9 @@  public:
       add_policy_operand ();
     if (m_needs_avl_p)
       add_avl_type_operand (m_vlmax_p ? avl_type::VLMAX : avl_type::NONVLMAX);
+
+    add_rounding_mode_operand ();
+
     expand (icode, any_mem_p);
   }
 
@@ -231,8 +253,10 @@  private:
   bool m_vlmax_p;
   bool m_has_tail_policy_p;
   bool m_has_mask_policy_p;
+  bool m_has_fp_rounding_mode_p;
   enum tail_policy m_tail_policy;
   enum mask_policy m_mask_policy;
+  enum rounding_mode m_fp_rounding_mode;
   machine_mode m_dest_mode;
   machine_mode m_mask_mode;
   rtx m_vl_op;
@@ -653,6 +677,48 @@  emit_vlmax_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
   e.emit_insn ((enum insn_code) icode, ops);
 }
 
+void
+emit_vlmax_fp_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (op_num,
+					  /* HAS_DEST_P */ true,
+					  /* FULLY_UNMASKED_P */ true,
+					  /* USE_REAL_MERGE_P */ false,
+					  /* HAS_AVL_P */ true,
+					  /* VLMAX_P */ true,
+					  dest_mode,
+					  mask_mode);
+
+  e.set_policy (TAIL_ANY);
+  e.set_policy (MASK_ANY);
+  e.set_rounding_mode (FRM_DYN);
+  e.set_vl (vl);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
+void
+emit_vlmax_fp_minmax_insn (unsigned icode, int op_num, rtx *ops, rtx vl)
+{
+  machine_mode dest_mode = GET_MODE (ops[0]);
+  machine_mode mask_mode = get_mask_mode (dest_mode).require ();
+  insn_expander<RVV_INSN_OPERANDS_MAX> e (op_num,
+					  /* HAS_DEST_P */ true,
+					  /* FULLY_UNMASKED_P */ true,
+					  /* USE_REAL_MERGE_P */ false,
+					  /* HAS_AVL_P */ true,
+					  /* VLMAX_P */ true,
+					  dest_mode,
+					  mask_mode);
+
+  e.set_policy (TAIL_ANY);
+  e.set_policy (MASK_ANY);
+
+  e.set_vl (vl);
+  e.emit_insn ((enum insn_code) icode, ops);
+}
+
 /* This function emits a {VLMAX, TAIL_ANY, MASK_ANY} vsetvli followed by the
  * ternary operation which always has a real merge operand.  */
 void
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index e5ae4e81b7a..c4588a55e04 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1306,11 +1306,22 @@  riscv_const_insns (rtx x)
 		if (satisfies_constraint_vi (x))
 		  return 1;
 
-		/* A const duplicate vector can always be broadcast from
-		   a general-purpose register.  This means we need as many
-		   insns as it takes to load the constant into the GPR
-		   and one vmv.v.x.  */
-		return 1 + riscv_const_insns (elt);
+		/* Any int/FP constants can always be broadcast from a
+		   scalar register.  Loading of a floating-point
+		   constant incurs a literal-pool access.  Allow this in
+		   order to increase vectorization possibilities.  */
+		int n = riscv_const_insns (elt);
+		if (CONST_DOUBLE_P (elt))
+		    return 1 + 4; /* vfmv.v.f + memory access.  */
+		else
+		  {
+		    /* We need as many insns as it takes to load the constant
+		       into a GPR and one vmv.v.x.  */
+		    if (n != 0)
+		      return 1 + n;
+		    else
+		      return 1 + 4; /*vmv.v.x + memory access.  */
+		  }
 	      }
 	  }
 
@@ -7209,8 +7220,8 @@  riscv_libgcc_floating_mode_supported_p (scalar_float_mode mode)
        precision of the _FloatN type; evaluate all other operations and
        constants to the range and precision of the semantic type;
 
-   If we have the zfh/zhinx extensions then we support _Float16 in native
-   precision, so we should set this to 16.  */
+   If we have the zfh/zhinx/zvfh extensions then we support _Float16
+   in native precision, so we should set this to 16.  */
 static enum flt_eval_method
 riscv_excess_precision (enum excess_precision_type type)
 {
@@ -7218,7 +7229,7 @@  riscv_excess_precision (enum excess_precision_type type)
     {
     case EXCESS_PRECISION_TYPE_FAST:
     case EXCESS_PRECISION_TYPE_STANDARD:
-      return ((TARGET_ZFH || TARGET_ZHINX)
+      return ((TARGET_ZFH || TARGET_ZHINX || TARGET_ZVFH)
 		? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
 		: FLT_EVAL_METHOD_PROMOTE_TO_FLOAT);
     case EXCESS_PRECISION_TYPE_IMPLICIT:
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 139d2b74d7c..e6040c1981c 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -317,6 +317,34 @@  (define_mode_iterator VF [
   (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
 ])
 
+;; This iterator is the same as above but with TARGET_VECTOR_ELEN_FP_16
+;; changed to TARGET_ZVFH.  TARGET_VECTOR_ELEN_FP_16 is also true for
+;; TARGET_ZVFHMIN while we actually disable all instructions apart from
+;; load, store and convert for it.
+;; Consequently the autovec expanders should also only be enabled with
+;; TARGET_ZVFH.
+(define_mode_iterator VF_AUTO [
+  (VNx1HF "TARGET_ZVFH && TARGET_MIN_VLEN < 128")
+  (VNx2HF "TARGET_ZVFH")
+  (VNx4HF "TARGET_ZVFH")
+  (VNx8HF "TARGET_ZVFH")
+  (VNx16HF "TARGET_ZVFH")
+  (VNx32HF "TARGET_ZVFH && TARGET_MIN_VLEN > 32")
+  (VNx64HF "TARGET_ZVFH && TARGET_MIN_VLEN >= 128")
+
+  (VNx1SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN < 128")
+  (VNx2SF "TARGET_VECTOR_ELEN_FP_32")
+  (VNx4SF "TARGET_VECTOR_ELEN_FP_32")
+  (VNx8SF "TARGET_VECTOR_ELEN_FP_32")
+  (VNx16SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN > 32")
+  (VNx32SF "TARGET_VECTOR_ELEN_FP_32 && TARGET_MIN_VLEN >= 128")
+  (VNx1DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN < 128")
+  (VNx2DF "TARGET_VECTOR_ELEN_FP_64")
+  (VNx4DF "TARGET_VECTOR_ELEN_FP_64")
+  (VNx8DF "TARGET_VECTOR_ELEN_FP_64")
+  (VNx16DF "TARGET_VECTOR_ELEN_FP_64 && TARGET_MIN_VLEN >= 128")
+])
+
 (define_mode_iterator VI_HAS_HALF [
    VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
    (VNx32SI "TARGET_MIN_VLEN >= 128")
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
index 65f61b0e932..7f05e589172 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-run.c
@@ -51,7 +51,9 @@ 
  RUN(int32_t, -3)	\
  RUN(uint32_t, 4)	\
  RUN(int64_t, -5)	\
- RUN(uint64_t, 6)    \
+ RUN(uint64_t, 6)	\
+ RUN(float, -5)		\
+ RUN(double, 6)		\
  RUN2(int8_t, -7)	\
  RUN2(uint8_t, 8)	\
  RUN2(int16_t, -7)	\
@@ -59,7 +61,9 @@ 
  RUN2(int32_t, -9)	\
  RUN2(uint32_t, 10)	\
  RUN2(int64_t, -11)	\
- RUN2(uint64_t, 12)   \
+ RUN2(uint64_t, 12)	\
+ RUN2(float, -11)	\
+ RUN2(double, 12)	\
  RUN3M(int8_t, 13)	\
  RUN3(uint8_t, 14)	\
  RUN3M(int16_t, 13)	\
@@ -67,7 +71,9 @@ 
  RUN3M(int32_t, 15)	\
  RUN3(uint32_t, 16)	\
  RUN3M(int64_t, 17)	\
- RUN3(uint64_t, 18)
+ RUN3(uint64_t, 18)	\
+ RUN3(float, 17)	\
+ RUN3M(double, 18)	\
 
 int main ()
 {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
index 2d094749c6a..cd0da74d8a5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv32gcv.c
@@ -1,7 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vadd-template.h"
 
 /* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */
 /* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfadd\.vv} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
index 4a1dc41c34a..30c3ef7bd4f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-rv64gcv.c
@@ -1,7 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vadd-template.h"
 
 /* { dg-final { scan-assembler-times {\tvadd\.vv} 16 } } */
 /* { dg-final { scan-assembler-times {\tvadd\.vi} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfadd\.vv} 9 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
index fecf2947691..e05b9c76275 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-template.h
@@ -41,6 +41,9 @@ 
  TEST_TYPE(uint32_t)	\
  TEST_TYPE(int64_t)	\
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16)	\
+ TEST_TYPE(float)	\
+ TEST_TYPE(double)	\
  TEST2_TYPE(int8_t)	\
  TEST2_TYPE(uint8_t)	\
  TEST2_TYPE(int16_t)	\
@@ -49,6 +52,9 @@ 
  TEST2_TYPE(uint32_t)	\
  TEST2_TYPE(int64_t)	\
  TEST2_TYPE(uint64_t)   \
+ TEST2_TYPE(_Float16)	\
+ TEST2_TYPE(float)	\
+ TEST2_TYPE(double)	\
  TEST3M_TYPE(int8_t)	\
  TEST3_TYPE(uint8_t)	\
  TEST3M_TYPE(int16_t)	\
@@ -56,6 +62,9 @@ 
  TEST3M_TYPE(int32_t)	\
  TEST3_TYPE(uint32_t)	\
  TEST3M_TYPE(int64_t)	\
- TEST3_TYPE(uint64_t)
+ TEST3_TYPE(uint64_t)   \
+ TEST3M_TYPE(_Float16)	\
+ TEST3_TYPE(float)	\
+ TEST3M_TYPE(double)	\
 
 TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
new file mode 100644
index 00000000000..595a5337939
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vadd-zvfh-run.c
@@ -0,0 +1,54 @@ 
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+
+#include "vadd-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL)				\
+  TYPE a##TYPE[SZ];				\
+  TYPE b##TYPE[SZ];	  			\
+  for (int i = 0; i < SZ; i++)			\
+  {                             		\
+    a##TYPE[i] = 0;             		\
+    b##TYPE[i] = VAL;           		\
+  }                             		\
+  vadd_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (a##TYPE[i] == VAL);
+
+#define RUN2(TYPE,VAL)				\
+  TYPE as##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as##TYPE[i] = 0;            		\
+  vadds_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as##TYPE[i] == VAL);
+
+#define RUN3(TYPE,VAL)				\
+  TYPE ai##TYPE[SZ];	  	        	\
+  for (int i = 0; i < SZ; i++)			\
+    ai##TYPE[i] = VAL;				\
+  vaddi_##TYPE (ai##TYPE, ai##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (ai##TYPE[i] == VAL + 15);
+
+#define RUN3M(TYPE,VAL)				\
+  TYPE aim##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    aim##TYPE[i] = VAL;				\
+  vaddim_##TYPE (aim##TYPE, aim##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (aim##TYPE[i] == VAL - 16);
+
+#define RUN_ALL()	\
+ RUN(_Float16, 4)	\
+ RUN2(_Float16, 10)	\
+ RUN3M(_Float16, 17)	\
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
index 810757a8834..9960c399b1f 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-run.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vdiv-template.h"
 
@@ -36,6 +36,8 @@ 
  RUN(uint32_t, 4)	\
  RUN(int64_t, -5)	\
  RUN(uint64_t, 6)	\
+ RUN(float, -5)		\
+ RUN(double, 6)		\
  RUN2(int8_t, -7)	\
  RUN2(uint8_t, 8)	\
  RUN2(int16_t, -7)	\
@@ -43,7 +45,9 @@ 
  RUN2(int32_t, -9)	\
  RUN2(uint32_t, 10)	\
  RUN2(int64_t, -11)	\
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12)	\
+ RUN2(float, -11)	\
+ RUN2(double, 12)	\
 
 int main ()
 {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
index 9f059ebc84c..604d9acb038 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv32gcv.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vdiv-template.h"
 
@@ -8,3 +8,8 @@ 
 
 /* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */
 /* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */
+
+/* Division by constant is done by calculating a reciprocal and
+   then multiplying.  Hence we do not expect 6 vfdivs.  */
+/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
index cd5d30b8974..26884035d57 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-rv64gcv.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vdiv-template.h"
 
@@ -8,3 +8,8 @@ 
 
 /* { dg-final { scan-assembler-times {\tvdiv\.vv} 14 } } */
 /* { dg-final { scan-assembler-times {\tvdivu\.vv} 14 } } */
+
+/* Division by constant is done by calculating a reciprocal and
+   then multiplying.  Hence we do not expect 6 vfdivs.  */
+/* { dg-final { scan-assembler-times {\tvfdiv\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
index fd9199722b6..7b0f579d1c9 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-template.h
@@ -25,6 +25,9 @@ 
  TEST_TYPE(uint32_t)	\
  TEST_TYPE(int64_t)	\
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16)	\
+ TEST_TYPE(float)	\
+ TEST_TYPE(double)	\
  TEST2_TYPE(int8_t)	\
  TEST2_TYPE(uint8_t)	\
  TEST2_TYPE(int16_t)	\
@@ -32,6 +35,9 @@ 
  TEST2_TYPE(int32_t)	\
  TEST2_TYPE(uint32_t)	\
  TEST2_TYPE(int64_t)	\
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t)	\
+ TEST2_TYPE(_Float16)	\
+ TEST2_TYPE(float)	\
+ TEST2_TYPE(double)	\
 
 TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
new file mode 100644
index 00000000000..c1c84e87a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vdiv-zvfh-run.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vdiv-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL)				\
+  TYPE a##TYPE[SZ];				\
+  TYPE b##TYPE[SZ];	  			\
+  for (int i = 0; i < SZ; i++)			\
+  {                             		\
+    a##TYPE[i] = VAL * 3;       		\
+    b##TYPE[i] = VAL;           		\
+  }                             		\
+  vdiv_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (a##TYPE[i] == 3);
+
+#define RUN2(TYPE,VAL)				\
+  TYPE as##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as##TYPE[i] = VAL * 5;			\
+  vdivs_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as##TYPE[i] == 5);
+
+#define RUN_ALL()	\
+ RUN(_Float16, 4)	\
+ RUN2(_Float16, 10)	\
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
index d889f28b298..da90fe8da33 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-run.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmax-template.h"
 
@@ -27,6 +27,7 @@ 
   for (int i = 0; i < SZ; i++)			\
     assert (as##TYPE[i] == 0 > VAL ? 0 : VAL);
 
+
 #define RUN_ALL()	\
  RUN(int8_t, -1)	\
  RUN(uint8_t, 2)	\
@@ -36,6 +37,8 @@ 
  RUN(uint32_t, 4)	\
  RUN(int64_t, -5)	\
  RUN(uint64_t, 6)	\
+ RUN(float, -5)		\
+ RUN(double, 6)		\
  RUN2(int8_t, -7)	\
  RUN2(uint8_t, 8)	\
  RUN2(int16_t, -7)	\
@@ -43,7 +46,9 @@ 
  RUN2(int32_t, -9)	\
  RUN2(uint32_t, 10)	\
  RUN2(int64_t, -11)	\
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12)	\
+ RUN2(float, -11)	\
+ RUN2(double, 12)	\
 
 int main ()
 {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
index 7b217d990a6..fbfa3ab057d 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv32gcv.c
@@ -1,7 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmax-template.h"
 
 /* { dg-final { scan-assembler-times {\tvmax\.vv} 8 } } */
 /* { dg-final { scan-assembler-times {\tvmaxu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmax\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
index 1b7f8c6be16..cf01ebc65f8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-rv64gcv.c
@@ -1,7 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmax-template.h"
 
 /* { dg-final { scan-assembler-times {\tvmax\.vv} 8 } } */
 /* { dg-final { scan-assembler-times {\tvmaxu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmax\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
index 6deb5126c7d..54828cd922a 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-template.h
@@ -25,6 +25,9 @@ 
  TEST_TYPE(uint32_t)	\
  TEST_TYPE(int64_t)	\
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16)	\
+ TEST_TYPE(float)	\
+ TEST_TYPE(double)	\
  TEST2_TYPE(int8_t)	\
  TEST2_TYPE(uint8_t)	\
  TEST2_TYPE(int16_t)	\
@@ -32,6 +35,9 @@ 
  TEST2_TYPE(int32_t)	\
  TEST2_TYPE(uint32_t)	\
  TEST2_TYPE(int64_t)	\
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t)	\
+ TEST2_TYPE(_Float16)	\
+ TEST2_TYPE(float)	\
+ TEST2_TYPE(double)	\
 
 TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
new file mode 100644
index 00000000000..1ab3d5d1199
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmax-zvfh-run.c
@@ -0,0 +1,38 @@ 
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vmax-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL)				\
+  TYPE a##TYPE[SZ];				\
+  TYPE b##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+  {                             		\
+    a##TYPE[i] = 0;             		\
+    b##TYPE[i] = VAL;           		\
+  }                             		\
+  vmax_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (a##TYPE[i] == 0 > VAL ? 0 : VAL);
+
+#define RUN2(TYPE,VAL)				\
+  TYPE as##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as##TYPE[i] = 0;				\
+  vmaxs_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as##TYPE[i] == 0 > VAL ? 0 : VAL);
+
+
+#define RUN_ALL()	\
+ RUN(_Float16, 4)	\
+ RUN2(_Float16, 10)	\
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
index a5887e6097f..e8ac9395d7b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-run.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmin-template.h"
 
@@ -35,7 +35,9 @@ 
  RUN(int32_t, -3)	\
  RUN(uint32_t, 4)	\
  RUN(int64_t, -5)	\
- RUN(uint64_t, 6)    \
+ RUN(uint64_t, 6)	\
+ RUN(float, -5)		\
+ RUN(double, 6)		\
  RUN2(int8_t, -7)	\
  RUN2(uint8_t, 8)	\
  RUN2(int16_t, -7)	\
@@ -43,7 +45,9 @@ 
  RUN2(int32_t, -9)	\
  RUN2(uint32_t, 10)	\
  RUN2(int64_t, -11)	\
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12)	\
+ RUN2(float, -11)	\
+ RUN2(double, 12)	\
 
 int main ()
 {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
index bf826ebf53a..87640732b3b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv32gcv.c
@@ -1,7 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmin-template.h"
 
 /* { dg-final { scan-assembler-times {\tvmin\.vv} 8 } } */
 /* { dg-final { scan-assembler-times {\tvminu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmin\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
index f57d4369006..193dacc82c5 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-rv64gcv.c
@@ -1,7 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmin-template.h"
 
 /* { dg-final { scan-assembler-times {\tvmin\.vv} 8 } } */
 /* { dg-final { scan-assembler-times {\tvminu\.vv} 8 } } */
+/* { dg-final { scan-assembler-times {\tvfmin\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
index 1225d5aca64..ca0d4e751e3 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-template.h
@@ -25,6 +25,9 @@ 
  TEST_TYPE(uint32_t)	\
  TEST_TYPE(int64_t)	\
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16)	\
+ TEST_TYPE(float)	\
+ TEST_TYPE(double)	\
  TEST2_TYPE(int8_t)	\
  TEST2_TYPE(uint8_t)	\
  TEST2_TYPE(int16_t)	\
@@ -32,6 +35,9 @@ 
  TEST2_TYPE(int32_t)	\
  TEST2_TYPE(uint32_t)	\
  TEST2_TYPE(int64_t)	\
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t)	\
+ TEST2_TYPE(_Float16)	\
+ TEST2_TYPE(float)	\
+ TEST2_TYPE(double)	\
 
 TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
new file mode 100644
index 00000000000..2d593542f0e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmin-zvfh-run.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vmin-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL)				\
+  TYPE a##TYPE[SZ];				\
+  TYPE b##TYPE[SZ];	  			\
+  for (int i = 0; i < SZ; i++)			\
+  {                             		\
+    a##TYPE[i] = 0;             		\
+    b##TYPE[i] = VAL;           		\
+  }                             		\
+  vmin_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (a##TYPE[i] == 0 < VAL ? 0 : VAL);
+
+#define RUN2(TYPE,VAL)				\
+  TYPE as##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as##TYPE[i] = 0;				\
+  vmins_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as##TYPE[i] == 0 < VAL ? 0 : VAL);
+
+#define RUN_ALL()	\
+ RUN(_Float16, 4)	\
+ RUN2(_Float16, 10)	\
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
index 22a2c1a18bb..60d0c906107 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-run.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmul-template.h"
 
@@ -36,6 +36,8 @@ 
  RUN(uint32_t, 4)	\
  RUN(int64_t, -5)	\
  RUN(uint64_t, 6)	\
+ RUN(float, -5)		\
+ RUN(double, 6)		\
  RUN2(int8_t, -7)	\
  RUN2(uint8_t, 8)	\
  RUN2(int16_t, -7)	\
@@ -43,7 +45,9 @@ 
  RUN2(int32_t, -9)	\
  RUN2(uint32_t, 10)	\
  RUN2(int64_t, -11)	\
- RUN2(uint64_t, 12)
+ RUN2(uint64_t, 12)	\
+ RUN2(float, -11)	\
+ RUN2(double, 12)	\
 
 int main ()
 {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
index f2dfa04cbe4..23656389d49 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv32gcv.c
@@ -1,11 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmul-template.h"
 
-<<<<<<< HEAD
-/* { dg-final { scan-assembler-times {\tvmul\.vv} 14 } } */
-=======
 /* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */
 /* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
->>>>>>> 1004a8ccd52 (fix  uint8)
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
index 91377299808..9ee3c6da38b 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-rv64gcv.c
@@ -1,11 +1,8 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vmul-template.h"
 
-<<<<<<< HEAD
-/* { dg-final { scan-assembler-times {\tvmul\.vv} 14 } } */
-=======
 /* { dg-final { scan-assembler-times {\tvmul\.vv} 16 } } */
 /* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
->>>>>>> 1004a8ccd52 (fix  uint8)
+/* { dg-final { scan-assembler-times {\tvfmul\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
index 33f9d87e1bb..4b81f52b065 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-template.h
@@ -25,6 +25,9 @@ 
  TEST_TYPE(uint32_t)	\
  TEST_TYPE(int64_t)	\
  TEST_TYPE(uint64_t)    \
+ TEST_TYPE(_Float16)	\
+ TEST_TYPE(float)	\
+ TEST_TYPE(double)	\
  TEST2_TYPE(int8_t)	\
  TEST2_TYPE(uint8_t)	\
  TEST2_TYPE(int16_t)	\
@@ -32,6 +35,9 @@ 
  TEST2_TYPE(int32_t)	\
  TEST2_TYPE(uint32_t)	\
  TEST2_TYPE(int64_t)	\
- TEST2_TYPE(uint64_t)
+ TEST2_TYPE(uint64_t)	\
+ TEST2_TYPE(_Float16)	\
+ TEST2_TYPE(float)	\
+ TEST2_TYPE(double)	\
 
 TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
new file mode 100644
index 00000000000..8f7c9c2848a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vmul-zvfh-run.c
@@ -0,0 +1,37 @@ 
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vmul-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL)				\
+  TYPE a##TYPE[SZ];				\
+  TYPE b##TYPE[SZ];	  			\
+  for (int i = 0; i < SZ; i++)			\
+  {                             		\
+    a##TYPE[i] = 2;				\
+    b##TYPE[i] = VAL;           		\
+  }                             		\
+  vadd_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (a##TYPE[i] == 2 * VAL);
+
+#define RUN2(TYPE,VAL)				\
+  TYPE as##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as##TYPE[i] = 3;            		\
+  vadds_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as##TYPE[i] == 3 * VAL);
+
+#define RUN_ALL()	\
+ RUN(_Float16, 4)	\
+ RUN2(_Float16, 10)	\
+
+int main ()
+{
+  RUN_ALL()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
index 7d2b478e1de..c6fe79e37b8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vrem-rv32gcv.c
@@ -1,5 +1,4 @@ 
-/* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vrem-template.h"
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
index a27b9de8862..90030c80316 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-run.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector_hw } } } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vsub-template.h"
 
@@ -52,6 +52,8 @@ 
  RUN(uint32_t, 4)	\
  RUN(int64_t, 5)	\
  RUN(uint64_t, 6)	\
+ RUN(float, 5)		\
+ RUN(double, 6)		\
  RUN2(int8_t, 7)	\
  RUN2(uint8_t, 8)	\
  RUN2(int16_t, 7)	\
@@ -60,6 +62,8 @@ 
  RUN2(uint32_t, 10)	\
  RUN2(int64_t, 11)	\
  RUN2(uint64_t, 12)	\
+ RUN2(float, 11)	\
+ RUN2(double, 12)	\
  RUN3(int8_t)		\
  RUN3(uint8_t)		\
  RUN3(int16_t)		\
@@ -68,6 +72,8 @@ 
  RUN3(uint32_t)		\
  RUN3(int64_t)		\
  RUN3(uint64_t)		\
+ RUN3(float)		\
+ RUN3(double)		\
  RUN4(int8_t)		\
  RUN4(uint8_t)		\
  RUN4(int16_t)		\
@@ -75,7 +81,9 @@ 
  RUN4(int32_t)		\
  RUN4(uint32_t)		\
  RUN4(int64_t)		\
- RUN4(uint64_t)
+ RUN4(uint64_t)		\
+ RUN4(float)		\
+ RUN4(double)		\
 
 int main ()
 {
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
index 5641432410e..f09d0664660 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv32gcv.c
@@ -1,7 +1,13 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vsub-template.h"
 
 /* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */
 /* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */
+
+/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */
+
+/* Do not expect vfrsub for now, because we do not properly
+   handle vop.vx and vfop.vf yet.  */
+/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
index 4fe0969c3a0..9f44f5fb5ab 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-rv64gcv.c
@@ -1,7 +1,13 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax" } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
 
 #include "vsub-template.h"
 
 /* { dg-final { scan-assembler-times {\tvsub\.vv} 16 } } */
 /* { dg-final { scan-assembler-times {\tvrsub\.vi} 16 } } */
+
+/* { dg-final { scan-assembler-times {\tvfsub\.vv} 12 } } */
+
+/* Do not expect vfrsub for now, because we do not properly
+   handle vop.vx and vfop.vf yet.  */
+/* { dg-final { scan-assembler-times {\tvfrsub\.vv} 0 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
index 222972d4752..d54b7ea6aa1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-template.h
@@ -41,8 +41,11 @@ 
  TEST_TYPE(uint32_t)	\
  TEST_TYPE(int64_t)	\
  TEST_TYPE(uint64_t)    \
- TEST2_TYPE(int8_t)	\
+ TEST_TYPE(_Float16)	\
+ TEST_TYPE(float)	\
+ TEST_TYPE(double)	\
 
+ TEST2_TYPE(int8_t)	\
  TEST2_TYPE(uint8_t)	\
  TEST2_TYPE(int16_t)	\
  TEST2_TYPE(uint16_t)	\
@@ -50,6 +53,9 @@ 
  TEST2_TYPE(uint32_t)	\
  TEST2_TYPE(int64_t)	\
  TEST2_TYPE(uint64_t)
+ TEST2_TYPE(_Float16)	\
+ TEST2_TYPE(float)	\
+ TEST2_TYPE(double)	\
 
  TEST3_TYPE(int8_t)	\
  TEST3_TYPE(uint8_t)	\
@@ -59,6 +65,9 @@ 
  TEST3_TYPE(uint32_t)	\
  TEST3_TYPE(int64_t)	\
  TEST3_TYPE(uint64_t)	\
+ TEST3_TYPE(_Float16)	\
+ TEST3_TYPE(float)	\
+ TEST3_TYPE(double)	\
 
  TEST4_TYPE(int8_t)	\
  TEST4_TYPE(uint8_t)	\
@@ -67,6 +76,9 @@ 
  TEST4_TYPE(int32_t)	\
  TEST4_TYPE(uint32_t)	\
  TEST4_TYPE(int64_t)	\
- TEST4_TYPE(uint64_t)
+ TEST4_TYPE(uint64_t)	\
+ TEST4_TYPE(_Float16)	\
+ TEST4_TYPE(float)	\
+ TEST4_TYPE(double)	\
 
 TEST_ALL()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
new file mode 100644
index 00000000000..262c938a0a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/binop/vsub-zvfh-run.c
@@ -0,0 +1,55 @@ 
+/* { dg-do run { target { riscv_zvfh_hw } } } */
+/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=fixed-vlmax -ffast-math" } */
+
+#include "vsub-template.h"
+
+#include <assert.h>
+
+#define SZ 512
+
+#define RUN(TYPE,VAL)				\
+  TYPE a##TYPE[SZ];				\
+  TYPE b##TYPE[SZ];	  			\
+  for (int i = 0; i < SZ; i++)			\
+  {                             		\
+    a##TYPE[i] = 999;           		\
+    b##TYPE[i] = VAL;           		\
+  }                             		\
+  vsub_##TYPE (a##TYPE, a##TYPE, b##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (a##TYPE[i] == 999 - VAL);
+
+#define RUN2(TYPE,VAL)				\
+  TYPE as##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as##TYPE[i] = 999;            		\
+  vsubs_##TYPE (as##TYPE, as##TYPE, VAL, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as##TYPE[i] == 999 - VAL);
+
+#define RUN3(TYPE)				\
+  TYPE as2##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as2##TYPE[i] = i * 33 - 779;            	\
+  vsubi_##TYPE (as2##TYPE, as2##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as2##TYPE[i] == (TYPE)(-16 - (i * 33 - 779)));
+
+#define RUN4(TYPE)				\
+  TYPE as3##TYPE[SZ];				\
+  for (int i = 0; i < SZ; i++)			\
+    as3##TYPE[i] = i * -17 + 667;            	\
+  vsubi2_##TYPE (as3##TYPE, as3##TYPE, SZ);	\
+  for (int i = 0; i < SZ; i++)			\
+    assert (as3##TYPE[i] == (TYPE)(15 - (i * -17 + 667)));
+
+#define RUN_ALL()	\
+ RUN(_Float16, 4)	\
+ RUN2(_Float16, 10)	\
+ RUN3(_Float16)		\
+ RUN4(_Float16)		\
+
+int main ()
+{
+  RUN_ALL()
+}