[V2] RISC-V: Support floating-point vfwadd/vfwsub vv/wv combine lowering

Message ID 20230628031011.138575-1-juzhe.zhong@rivai.ai
State Unresolved
Headers
Series [V2] RISC-V: Support floating-point vfwadd/vfwsub vv/wv combine lowering |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

juzhe.zhong@rivai.ai June 28, 2023, 3:10 a.m. UTC
  Currently, vfwadd.wv is the pattern with (set (reg) (float_extend:(reg)) which makes
combine pass faile to combine.

change RTL format of vfwadd.wv ------> (set (float_extend:(reg) (reg)) so that combine
PASS can combine.

gcc/ChangeLog:

        * config/riscv/riscv-vector-builtins-bases.cc: Adapt expand.
        * config/riscv/vector.md (@pred_single_widen_<plus_minus:optab><mode>): Remove.
        (@pred_single_widen_add<mode>): New pattern.
        (@pred_single_widen_sub<mode>): New pattern.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/autovec/widen/widen-1.c: Add floating-point.
        * gcc.target/riscv/rvv/autovec/widen/widen-2.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen-5.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen-6.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen_run-1.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen_run-2.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen_run-5.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen_run-6.c: Ditto.
        * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c: New test.
        * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c: New test.
        * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c: New test.
        * gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c: New test.

---
 .../riscv/riscv-vector-builtins-bases.cc      |  8 +++--
 gcc/config/riscv/vector.md                    | 31 ++++++++++++++++---
 .../riscv/rvv/autovec/widen/widen-1.c         |  7 +++--
 .../riscv/rvv/autovec/widen/widen-2.c         |  7 +++--
 .../riscv/rvv/autovec/widen/widen-5.c         |  7 +++--
 .../riscv/rvv/autovec/widen/widen-6.c         |  7 +++--
 .../rvv/autovec/widen/widen-complicate-1.c    |  7 +++--
 .../rvv/autovec/widen/widen-complicate-2.c    |  7 +++--
 .../riscv/rvv/autovec/widen/widen_run-1.c     |  5 +--
 .../riscv/rvv/autovec/widen/widen_run-2.c     |  5 +--
 .../riscv/rvv/autovec/widen/widen_run-5.c     |  5 +--
 .../riscv/rvv/autovec/widen/widen_run-6.c     |  5 +--
 .../rvv/autovec/widen/widen_run_zvfh-1.c      | 28 +++++++++++++++++
 .../rvv/autovec/widen/widen_run_zvfh-2.c      | 28 +++++++++++++++++
 .../rvv/autovec/widen/widen_run_zvfh-5.c      | 28 +++++++++++++++++
 .../rvv/autovec/widen/widen_run_zvfh-6.c      | 28 +++++++++++++++++
 16 files changed, 187 insertions(+), 26 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c
  

Comments

Kito Cheng June 28, 2023, 3:15 a.m. UTC | #1
LGTM with a minor comment.

> Currently, vfwadd.wv is the pattern with (set (reg) (float_extend:(reg)) which makes

it's minor so you can just go commit after the fix: this should be
(set (plus (reg) (float_extend:(reg)))

> combine pass faile to combine.
>
> change RTL format of vfwadd.wv ------> (set (float_extend:(reg) (reg)) so that combine

and (set (plus (float_extend:(reg) (reg)))

> PASS can combine.
  

Patch

diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index fb74cb36ebd..f4a061a831b 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -390,8 +390,12 @@  public:
 	return e.use_exact_insn (
 	  code_for_pred_dual_widen_scalar (CODE, e.vector_mode ()));
       case OP_TYPE_wv:
-	return e.use_exact_insn (
-	  code_for_pred_single_widen (CODE, e.vector_mode ()));
+	if (CODE == PLUS)
+	  return e.use_exact_insn (
+	    code_for_pred_single_widen_add (e.vector_mode ()));
+	else
+	  return e.use_exact_insn (
+	    code_for_pred_single_widen_sub (e.vector_mode ()));
       case OP_TYPE_wf:
 	return e.use_exact_insn (
 	  code_for_pred_single_widen_scalar (CODE, e.vector_mode ()));
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index b0b3b0ed977..406f96439ec 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -6574,7 +6574,7 @@ 
   [(set_attr "type" "vf<widen_binop_insn_type>")
    (set_attr "mode" "<V_DOUBLE_TRUNC>")])
 
-(define_insn "@pred_single_widen_<plus_minus:optab><mode>"
+(define_insn "@pred_single_widen_add<mode>"
   [(set (match_operand:VWEXTF 0 "register_operand"                  "=&vr,  &vr")
 	(if_then_else:VWEXTF
 	  (unspec:<VM>
@@ -6587,14 +6587,37 @@ 
 	     (reg:SI VL_REGNUM)
 	     (reg:SI VTYPE_REGNUM)
 	     (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-	  (plus_minus:VWEXTF
+	  (plus:VWEXTF
+	    (float_extend:VWEXTF
+	      (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "   vr,   vr"))
+	    (match_operand:VWEXTF 3 "register_operand"             "   vr,   vr"))
+	  (match_operand:VWEXTF 2 "vector_merge_operand"           "   vu,    0")))]
+  "TARGET_VECTOR"
+  "vfwadd.wv\t%0,%3,%4%p1"
+  [(set_attr "type" "vfwalu")
+   (set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+(define_insn "@pred_single_widen_sub<mode>"
+  [(set (match_operand:VWEXTF 0 "register_operand"                  "=&vr,  &vr")
+	(if_then_else:VWEXTF
+	  (unspec:<VM>
+	    [(match_operand:<VM> 1 "vector_mask_operand"           "vmWc1,vmWc1")
+	     (match_operand 5 "vector_length_operand"              "   rK,   rK")
+	     (match_operand 6 "const_int_operand"                  "    i,    i")
+	     (match_operand 7 "const_int_operand"                  "    i,    i")
+	     (match_operand 8 "const_int_operand"                  "    i,    i")
+	     (match_operand 9 "const_int_operand"                  "    i,    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)
+	     (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
+	  (minus:VWEXTF
 	    (match_operand:VWEXTF 3 "register_operand"             "   vr,   vr")
 	    (float_extend:VWEXTF
 	      (match_operand:<V_DOUBLE_TRUNC> 4 "register_operand" "   vr,   vr")))
 	  (match_operand:VWEXTF 2 "vector_merge_operand"           "   vu,    0")))]
   "TARGET_VECTOR"
-  "vfw<insn>.wv\t%0,%3,%4%p1"
-  [(set_attr "type" "vf<widen_binop_insn_type>")
+  "vfwsub.wv\t%0,%3,%4%p1"
+  [(set_attr "type" "vfwalu")
    (set_attr "mode" "<V_DOUBLE_TRUNC>")])
 
 (define_insn "@pred_single_widen_<plus_minus:optab><mode>_scalar"
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c
index 00edecab089..e2ec4ee9b99 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -19,9 +19,12 @@ 
   TEST_TYPE (int32_t, int16_t)                                                 \
   TEST_TYPE (uint32_t, uint16_t)                                               \
   TEST_TYPE (int64_t, int32_t)                                                 \
-  TEST_TYPE (uint64_t, uint32_t)
+  TEST_TYPE (uint64_t, uint32_t)                                               \
+  TEST_TYPE (float, _Float16)                                                  \
+  TEST_TYPE (double, float)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvwadd\.vv} 3 } } */
 /* { dg-final { scan-assembler-times {\tvwaddu\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwadd\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c
index 4d370f583b7..246acf22dd8 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -19,9 +19,12 @@ 
   TEST_TYPE (int32_t, int16_t)                                                 \
   TEST_TYPE (uint32_t, uint16_t)                                               \
   TEST_TYPE (int64_t, int32_t)                                                 \
-  TEST_TYPE (uint64_t, uint32_t)
+  TEST_TYPE (uint64_t, uint32_t)                                               \
+  TEST_TYPE (float, _Float16)                                                  \
+  TEST_TYPE (double, float)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvwsub\.vv} 3 } } */
 /* { dg-final { scan-assembler-times {\tvwsubu\.vv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwsub\.vv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c
index 7f8909272ab..62b121d7bbd 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-5.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -19,9 +19,12 @@ 
   TEST_TYPE (int32_t, int16_t)                                                 \
   TEST_TYPE (uint32_t, uint16_t)                                               \
   TEST_TYPE (int64_t, int32_t)                                                 \
-  TEST_TYPE (uint64_t, uint32_t)
+  TEST_TYPE (uint64_t, uint32_t)                                               \
+  TEST_TYPE (float, _Float16)                                                  \
+  TEST_TYPE (double, float)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvwadd\.wv} 3 } } */
 /* { dg-final { scan-assembler-times {\tvwaddu\.wv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwadd\.wv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c
index f9542d7601e..cd4853778cf 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-6.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -19,9 +19,12 @@ 
   TEST_TYPE (int32_t, int16_t)                                                 \
   TEST_TYPE (uint32_t, uint16_t)                                               \
   TEST_TYPE (int64_t, int32_t)                                                 \
-  TEST_TYPE (uint64_t, uint32_t)
+  TEST_TYPE (uint64_t, uint32_t)                                               \
+  TEST_TYPE (float, _Float16)                                                  \
+  TEST_TYPE (double, float)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvwsub\.wv} 3 } } */
 /* { dg-final { scan-assembler-times {\tvwsubu\.wv} 3 } } */
+/* { dg-final { scan-assembler-times {\tvfwsub\.wv} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c
index baf91b72d60..83e16c606d1 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -23,9 +23,12 @@ 
   TEST_TYPE (int32_t, int16_t)                                                 \
   TEST_TYPE (uint32_t, uint16_t)                                               \
   TEST_TYPE (int64_t, int32_t)                                                 \
-  TEST_TYPE (uint64_t, uint32_t)
+  TEST_TYPE (uint64_t, uint32_t)                                               \
+  TEST_TYPE (float, _Float16)                                                  \
+  TEST_TYPE (double, float)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvwadd\.vv} 9 } } */
 /* { dg-final { scan-assembler-times {\tvwaddu\.vv} 9 } } */
+/* { dg-final { scan-assembler-times {\tvfwadd\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c
index 6d1709bf2f6..97036e64d94 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen-complicate-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "-march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <stdint-gcc.h>
 
@@ -23,9 +23,12 @@ 
   TEST_TYPE (int32_t, int16_t)                                                 \
   TEST_TYPE (uint32_t, uint16_t)                                               \
   TEST_TYPE (int64_t, int32_t)                                                 \
-  TEST_TYPE (uint64_t, uint32_t)
+  TEST_TYPE (uint64_t, uint32_t)                                               \
+  TEST_TYPE (float, _Float16)                                                  \
+  TEST_TYPE (double, float)
 
 TEST_ALL ()
 
 /* { dg-final { scan-assembler-times {\tvwsub\.vv} 9 } } */
 /* { dg-final { scan-assembler-times {\tvwsubu\.vv} 9 } } */
+/* { dg-final { scan-assembler-times {\tvfwsub\.vv} 6 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c
index 6cdeb571711..21d0934ad09 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <assert.h>
 #include "widen-1.c"
@@ -25,7 +25,8 @@ 
   RUN (int32_t, int16_t, -32768)                                               \
   RUN (uint32_t, uint16_t, 65535)                                              \
   RUN (int64_t, int32_t, -2147483648)                                          \
-  RUN (uint64_t, uint32_t, 4294967295)
+  RUN (uint64_t, uint32_t, 4294967295)                                         \
+  RUN (double, float, -2147483648)
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c
index 84baa515610..e5805a9a5bb 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <assert.h>
 #include "widen-2.c"
@@ -25,7 +25,8 @@ 
   RUN (int32_t, int16_t, -32768)                                               \
   RUN (uint32_t, uint16_t, 65535)                                              \
   RUN (int64_t, int32_t, -2147483648)                                          \
-  RUN (uint64_t, uint32_t, 4294967295)
+  RUN (uint64_t, uint32_t, 4294967295)                                         \
+  RUN (double, float, -2147483648)
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c
index ca16585a945..d94f7044087 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-5.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <assert.h>
 #include "widen-5.c"
@@ -25,7 +25,8 @@ 
   RUN (int32_t, int16_t, -32768)                                               \
   RUN (uint32_t, uint16_t, 65535)                                              \
   RUN (int64_t, int32_t, -2147483648)                                          \
-  RUN (uint64_t, uint32_t, 4294967295)
+  RUN (uint64_t, uint32_t, 4294967295)                                         \
+  RUN (double, float, -2147483648)
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c
index 5b69c2ab0c6..6c4ccece141 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run-6.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run { target { riscv_vector } } } */
-/* { dg-additional-options "--param=riscv-autovec-preference=scalable" } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
 
 #include <assert.h>
 #include "widen-6.c"
@@ -25,7 +25,8 @@ 
   RUN (int32_t, int16_t, -32768)                                               \
   RUN (uint32_t, uint16_t, 65535)                                              \
   RUN (int64_t, int32_t, -2147483648)                                          \
-  RUN (uint64_t, uint32_t, 4294967295)
+  RUN (uint64_t, uint32_t, 4294967295)                                         \
+  RUN (double, float, -2147483648)
 
 int
 main ()
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c
new file mode 100644
index 00000000000..e70f06f5381
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-1.c
@@ -0,0 +1,28 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-1.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT)                                               \
+  TYPE2 a##TYPE2[SZ];                                                          \
+  TYPE2 b##TYPE2[SZ];                                                          \
+  TYPE1 dst##TYPE1[SZ];                                                        \
+  for (int i = 0; i < SZ; i++)                                                 \
+    {                                                                          \
+      a##TYPE2[i] = LIMIT + i % 8723;                                          \
+      b##TYPE2[i] = LIMIT + i & 1964;                                          \
+    }                                                                          \
+  vwadd_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ);                  \
+  for (int i = 0; i < SZ; i++)                                                 \
+    assert (dst##TYPE1[i] == ((TYPE1) a##TYPE2[i] + (TYPE1) b##TYPE2[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+  RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c
new file mode 100644
index 00000000000..e07a82871a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-2.c
@@ -0,0 +1,28 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-2.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT)                                               \
+  TYPE2 a##TYPE2[SZ];                                                          \
+  TYPE2 b##TYPE2[SZ];                                                          \
+  TYPE1 dst##TYPE1[SZ];                                                        \
+  for (int i = 0; i < SZ; i++)                                                 \
+    {                                                                          \
+      a##TYPE2[i] = LIMIT + i % 8723;                                          \
+      b##TYPE2[i] = LIMIT + i & 1964;                                          \
+    }                                                                          \
+  vwsub_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE2, SZ);                  \
+  for (int i = 0; i < SZ; i++)                                                 \
+    assert (dst##TYPE1[i] == ((TYPE1) a##TYPE2[i] - (TYPE1) b##TYPE2[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+  RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c
new file mode 100644
index 00000000000..144e3d2b02b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-5.c
@@ -0,0 +1,28 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-5.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT)                                               \
+  TYPE2 a##TYPE2[SZ];                                                          \
+  TYPE1 b##TYPE1[SZ];                                                          \
+  TYPE1 dst##TYPE1[SZ];                                                        \
+  for (int i = 0; i < SZ; i++)                                                 \
+    {                                                                          \
+      a##TYPE2[i] = LIMIT + i % 8723;                                          \
+      b##TYPE1[i] = LIMIT + i & 1964;                                          \
+    }                                                                          \
+  vwadd_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE2, b##TYPE1, SZ);                  \
+  for (int i = 0; i < SZ; i++)                                                 \
+    assert (dst##TYPE1[i] == ((TYPE1) a##TYPE2[i] + (TYPE1) b##TYPE1[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+  RUN_ALL ()
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c
new file mode 100644
index 00000000000..006dadec067
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/widen/widen_run_zvfh-6.c
@@ -0,0 +1,28 @@ 
+/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */
+/* { dg-additional-options "--param=riscv-autovec-preference=scalable -ffast-math" } */
+
+#include <assert.h>
+#include "widen-6.c"
+
+#define SZ 512
+
+#define RUN(TYPE1, TYPE2, LIMIT)                                               \
+  TYPE1 a##TYPE1[SZ];                                                          \
+  TYPE2 b##TYPE2[SZ];                                                          \
+  TYPE1 dst##TYPE1[SZ];                                                        \
+  for (int i = 0; i < SZ; i++)                                                 \
+    {                                                                          \
+      a##TYPE1[i] = LIMIT + i % 8723;                                          \
+      b##TYPE2[i] = LIMIT + i & 1964;                                          \
+    }                                                                          \
+  vwsub_##TYPE1_##TYPE2 (dst##TYPE1, a##TYPE1, b##TYPE2, SZ);                  \
+  for (int i = 0; i < SZ; i++)                                                 \
+    assert (dst##TYPE1[i] == ((TYPE1) a##TYPE1[i] - (TYPE1) b##TYPE2[i]));
+
+#define RUN_ALL() RUN (float, _Float16, -32768)
+
+int
+main ()
+{
+  RUN_ALL ()
+}