[v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64

Message ID 20230618151329.1814812-1-pan2.li@intel.com
State Unresolved
Headers
Series [v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64 |

Checks

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

Commit Message

Li, Pan2 via Gcc-patches June 18, 2023, 3:13 p.m. UTC
  From: Pan Li <pan2.li@intel.com>

The rvv widdening reduction has 3 different patterns for zve128+, zve64
and zve32. They take the same iterator with different attributions.
However, we need the generated function code_for_reduc (code, mode1, mode2).
The implementation of code_for_reduc may look like below.

code_for_reduc (code, mode1, mode2)
{
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx16hf; // ZVE128+

  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx8hf;  // ZVE64

  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx4hf;  // ZVE32
}

Thus there will be a problem here. For example zve32, we will have
code_for_reduc (max, VNx1HF, VNx1HF) which will return the code of
the ZVE128+ instead of the ZVE32 logically.

This patch will merge the 3 patterns into pattern, and pass both the
input_vector and the ret_vector of code_for_reduc. For example, ZVE32
will be code_for_reduc (max, VNx1HF, VNx2HF), then the correct code of ZVE32
will be returned as expectation.

Please note both GCC 13 and 14 are impacted by this issue.

Signed-off-by: Pan Li <pan2.li@intel.com>
Co-Authored by: Juzhe-Zhong <juzhe.zhong@rivai.ai>

	PR 110299

gcc/ChangeLog:

	* config/riscv/riscv-vector-builtins-bases.cc: Adjust expand for
	modes.
	* config/riscv/vector-iterators.md: Remove VWLMUL1, VWLMUL1_ZVE64,
	VWLMUL1_ZVE32.
	* config/riscv/vector.md
	(@pred_widen_reduc_plus<v_su><mode><vwlmul1>): Removed.
	(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>): Ditto.
	(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>): Ditto.
	(@pred_widen_reduc_plus<order><mode><vwlmul1>): Ditto.
	(@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>): Ditto.
	(@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>): New pattern.
	(@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>): Ditto.
	(@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>): Ditto.
	(@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>): Ditto.
	(@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>): Ditto.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/pr110299-1.c: New test.
	* gcc.target/riscv/rvv/base/pr110299-1.h: New test.
	* gcc.target/riscv/rvv/base/pr110299-2.c: New test.
	* gcc.target/riscv/rvv/base/pr110299-2.h: New test.
	* gcc.target/riscv/rvv/base/pr110299-3.c: New test.
	* gcc.target/riscv/rvv/base/pr110299-3.h: New test.
	* gcc.target/riscv/rvv/base/pr110299-4.c: New test.
	* gcc.target/riscv/rvv/base/pr110299-4.h: New test.
---
 .../riscv/riscv-vector-builtins-bases.cc      |  16 +-
 gcc/config/riscv/vector-iterators.md          |  62 -----
 gcc/config/riscv/vector.md                    | 243 ++++++++++++------
 .../gcc.target/riscv/rvv/base/pr110299-1.c    |   7 +
 .../gcc.target/riscv/rvv/base/pr110299-1.h    |   9 +
 .../gcc.target/riscv/rvv/base/pr110299-2.c    |   8 +
 .../gcc.target/riscv/rvv/base/pr110299-2.h    |  17 ++
 .../gcc.target/riscv/rvv/base/pr110299-3.c    |   7 +
 .../gcc.target/riscv/rvv/base/pr110299-3.h    |  17 ++
 .../gcc.target/riscv/rvv/base/pr110299-4.c    |   8 +
 .../gcc.target/riscv/rvv/base/pr110299-4.h    |  17 ++
 11 files changed, 253 insertions(+), 158 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
  

Comments

juzhe.zhong@rivai.ai June 18, 2023, 10:01 p.m. UTC | #1
Add target into changelog:
PR target/110299

Otherwise, LGTM.


juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-06-18 23:13
To: gcc-patches
CC: juzhe.zhong; rdapp.gcc; jeffreyalaw; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64
From: Pan Li <pan2.li@intel.com>
 
The rvv widdening reduction has 3 different patterns for zve128+, zve64
and zve32. They take the same iterator with different attributions.
However, we need the generated function code_for_reduc (code, mode1, mode2).
The implementation of code_for_reduc may look like below.
 
code_for_reduc (code, mode1, mode2)
{
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx16hf; // ZVE128+
 
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx8hf;  // ZVE64
 
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx4hf;  // ZVE32
}
 
Thus there will be a problem here. For example zve32, we will have
code_for_reduc (max, VNx1HF, VNx1HF) which will return the code of
the ZVE128+ instead of the ZVE32 logically.
 
This patch will merge the 3 patterns into pattern, and pass both the
input_vector and the ret_vector of code_for_reduc. For example, ZVE32
will be code_for_reduc (max, VNx1HF, VNx2HF), then the correct code of ZVE32
will be returned as expectation.
 
Please note both GCC 13 and 14 are impacted by this issue.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
Co-Authored by: Juzhe-Zhong <juzhe.zhong@rivai.ai>
 
PR 110299
 
gcc/ChangeLog:
 
* config/riscv/riscv-vector-builtins-bases.cc: Adjust expand for
modes.
* config/riscv/vector-iterators.md: Remove VWLMUL1, VWLMUL1_ZVE64,
VWLMUL1_ZVE32.
* config/riscv/vector.md
(@pred_widen_reduc_plus<v_su><mode><vwlmul1>): Removed.
(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>): Ditto.
(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>): Ditto.
(@pred_widen_reduc_plus<order><mode><vwlmul1>): Ditto.
(@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>): Ditto.
(@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>): New pattern.
(@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>): Ditto.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr110299-1.c: New test.
* gcc.target/riscv/rvv/base/pr110299-1.h: New test.
* gcc.target/riscv/rvv/base/pr110299-2.c: New test.
* gcc.target/riscv/rvv/base/pr110299-2.h: New test.
* gcc.target/riscv/rvv/base/pr110299-3.c: New test.
* gcc.target/riscv/rvv/base/pr110299-3.h: New test.
* gcc.target/riscv/rvv/base/pr110299-4.c: New test.
* gcc.target/riscv/rvv/base/pr110299-4.h: New test.
---
.../riscv/riscv-vector-builtins-bases.cc      |  16 +-
gcc/config/riscv/vector-iterators.md          |  62 -----
gcc/config/riscv/vector.md                    | 243 ++++++++++++------
.../gcc.target/riscv/rvv/base/pr110299-1.c    |   7 +
.../gcc.target/riscv/rvv/base/pr110299-1.h    |   9 +
.../gcc.target/riscv/rvv/base/pr110299-2.c    |   8 +
.../gcc.target/riscv/rvv/base/pr110299-2.h    |  17 ++
.../gcc.target/riscv/rvv/base/pr110299-3.c    |   7 +
.../gcc.target/riscv/rvv/base/pr110299-3.h    |  17 ++
.../gcc.target/riscv/rvv/base/pr110299-4.c    |   8 +
.../gcc.target/riscv/rvv/base/pr110299-4.h    |  17 ++
11 files changed, 253 insertions(+), 158 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
 
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 27545113996..c6c53dc13a5 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -1396,16 +1396,8 @@ public:
   rtx expand (function_expander &e) const override
   {
-    machine_mode mode = e.vector_mode ();
-    machine_mode ret_mode = e.ret_mode ();
-
-    /* TODO: we will use ret_mode after all types of PR110265 are addressed.  */
-    if (GET_MODE_INNER (mode) != GET_MODE_INNER (ret_mode))
-      return e.use_exact_insn (
- code_for_pred_reduc (CODE, e.vector_mode (), e.vector_mode ()));
-    else
-      return e.use_exact_insn (
- code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
+    return e.use_exact_insn (
+      code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
   }
};
@@ -1420,7 +1412,7 @@ public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
     e.vector_mode (),
-      e.vector_mode ()));
+      e.ret_mode ()));
   }
};
@@ -1449,7 +1441,7 @@ public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
     e.vector_mode (),
-      e.vector_mode ()));
+      e.ret_mode ()));
   }
};
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 6169116482a..e4c6c1bb135 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1392,68 +1392,6 @@ (define_mode_attr VNCONVERT [
   (VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI") (VNx16DF "VNx16SI")
])
-(define_mode_attr VWLMUL1 [
-  (VNx1QI "VNx8HI") (VNx2QI "VNx8HI") (VNx4QI "VNx8HI")
-  (VNx8QI "VNx8HI") (VNx16QI "VNx8HI") (VNx32QI "VNx8HI") (VNx64QI "VNx8HI") (VNx128QI "VNx8HI")
-  (VNx1HI "VNx4SI") (VNx2HI "VNx4SI") (VNx4HI "VNx4SI")
-  (VNx8HI "VNx4SI") (VNx16HI "VNx4SI") (VNx32HI "VNx4SI") (VNx64HI "VNx4SI")
-  (VNx1SI "VNx2DI") (VNx2SI "VNx2DI") (VNx4SI "VNx2DI")
-  (VNx8SI "VNx2DI") (VNx16SI "VNx2DI") (VNx32SI "VNx2DI")
-  (VNx1HF "VNx4SF") (VNx2HF "VNx4SF") (VNx4HF "VNx4SF") (VNx8HF "VNx4SF") (VNx16HF "VNx4SF") (VNx32HF "VNx4SF") (VNx64HF "VNx4SF")
-  (VNx1SF "VNx2DF") (VNx2SF "VNx2DF")
-  (VNx4SF "VNx2DF") (VNx8SF "VNx2DF") (VNx16SF "VNx2DF") (VNx32SF "VNx2DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE64 [
-  (VNx1QI "VNx4HI") (VNx2QI "VNx4HI") (VNx4QI "VNx4HI")
-  (VNx8QI "VNx4HI") (VNx16QI "VNx4HI") (VNx32QI "VNx4HI") (VNx64QI "VNx4HI")
-  (VNx1HI "VNx2SI") (VNx2HI "VNx2SI") (VNx4HI "VNx2SI")
-  (VNx8HI "VNx2SI") (VNx16HI "VNx2SI") (VNx32HI "VNx2SI")
-  (VNx1SI "VNx1DI") (VNx2SI "VNx1DI") (VNx4SI "VNx1DI")
-  (VNx8SI "VNx1DI") (VNx16SI "VNx1DI")
-  (VNx1HF "VNx2SF") (VNx2HF "VNx2SF") (VNx4HF "VNx2SF") (VNx8HF "VNx2SF") (VNx16HF "VNx2SF") (VNx32HF "VNx2SF")
-  (VNx1SF "VNx1DF") (VNx2SF "VNx1DF")
-  (VNx4SF "VNx1DF") (VNx8SF "VNx1DF") (VNx16SF "VNx1DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE32 [
-  (VNx1QI "VNx2HI") (VNx2QI "VNx2HI") (VNx4QI "VNx2HI")
-  (VNx8QI "VNx2HI") (VNx16QI "VNx2HI") (VNx32QI "VNx2HI")
-  (VNx1HI "VNx1SI") (VNx2HI "VNx1SI") (VNx4HI "VNx1SI")
-  (VNx8HI "VNx1SI") (VNx16HI "VNx1SI")
-])
-
-(define_mode_attr vwlmul1 [
-  (VNx1QI "vnx8hi") (VNx2QI "vnx8hi") (VNx4QI "vnx8hi")
-  (VNx8QI "vnx8hi") (VNx16QI "vnx8hi") (VNx32QI "vnx8hi") (VNx64QI "vnx8hi") (VNx128QI "vnx8hi")
-  (VNx1HI "vnx4si") (VNx2HI "vnx4si") (VNx4HI "vnx4si")
-  (VNx8HI "vnx4si") (VNx16HI "vnx4si") (VNx32HI "vnx4si") (VNx64HI "vnx4si")
-  (VNx1SI "vnx2di") (VNx2SI "vnx2di") (VNx4SI "vnx2di")
-  (VNx8SI "vnx2di") (VNx16SI "vnx2di") (VNx32SI "vnx2di")
-  (VNx1HF "vnx4sf") (VNx2HF "vnx4sf") (VNx4HF "vnx4sf") (VNx8HF "vnx4sf") (VNx16HF "vnx4sf") (VNx32HF "vnx4sf") (VNx64HF "vnx4sf")
-  (VNx1SF "vnx2df") (VNx2SF "vnx2df")
-  (VNx4SF "vnx2df") (VNx8SF "vnx2df") (VNx16SF "vnx2df") (VNx32SF "vnx2df")
-])
-
-(define_mode_attr vwlmul1_zve64 [
-  (VNx1QI "vnx4hi") (VNx2QI "vnx4hi") (VNx4QI "vnx4hi")
-  (VNx8QI "vnx4hi") (VNx16QI "vnx4hi") (VNx32QI "vnx4hi") (VNx64QI "vnx4hi")
-  (VNx1HI "vnx2si") (VNx2HI "vnx2si") (VNx4HI "vnx2si")
-  (VNx8HI "vnx2si") (VNx16HI "vnx2si") (VNx32HI "vnx2si")
-  (VNx1SI "vnx1di") (VNx2SI "vnx1di") (VNx4SI "vnx1di")
-  (VNx8SI "vnx1di") (VNx16SI "vnx1di")
-  (VNx1HF "vnx2sf") (VNx2HF "vnx2sf") (VNx4HF "vnx2sf") (VNx8HF "vnx2sf") (VNx16HF "vnx2sf") (VNx32HF "vnx2sf")
-  (VNx1SF "vnx1df") (VNx2SF "vnx1df")
-  (VNx4SF "vnx1df") (VNx8SF "vnx1df") (VNx16SF "vnx1df")
-])
-
-(define_mode_attr vwlmul1_zve32 [
-  (VNx1QI "vnx2hi") (VNx2QI "vnx2hi") (VNx4QI "vnx2hi")
-  (VNx8QI "vnx2hi") (VNx16QI "vnx2hi") (VNx32QI "vnx2hi")
-  (VNx1HI "vnx1si") (VNx2HI "vnx1si") (VNx4HI "vnx1si")
-  (VNx8HI "vnx1si") (VNx16HI "vnx1si")
-])
-
(define_mode_attr VDEMOTE [
   (VNx1DI "VNx2SI") (VNx2DI "VNx4SI")
   (VNx4DI "VNx8SI") (VNx8DI "VNx16SI") (VNx16DI "VNx32SI")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index efce992a012..884e7435cc2 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -7407,60 +7407,101 @@ (define_insn "@pred_reduc_<reduc><VDI:mode><VDI_LMUL1:mode>"
   ]
)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1>
-   [(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")
+;; Integer Reduction Widen for QI, HI = QI op HI
+(define_insn "@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VHI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VHI_LMUL1
+ [
+   (unspec:<VQI:VM>
+     [
+       (match_operand:<VQI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VQI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VHI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VHI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VQI:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE64>
-   [(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")
+;; Integer Reduction Widen for HI, SI = HI op SI
+(define_insn "@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VSI_LMUL1
+ [
+   (unspec:<VHI:VM>
+     [
+       (match_operand:<VHI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI_ZVE64 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VHI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VSI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VSI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
-
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VHI:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>"
-  [(set (match_operand:<VWLMUL1_ZVE32> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE32>
-   [(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")
+;; Integer Reduction Widen for SI, DI = SI op DI
+(define_insn "@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VDI_LMUL1
+ [
+   (unspec:<VSI:VM>
+     [
+       (match_operand:<VSI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI_ZVE32 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE32> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE32> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VSI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VDI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VDI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VSI:MODE>")
+  ]
+)
;; Float Reduction for HF
(define_insn "@pred_reduc_<reduc><VHF:mode><VHF_LMUL1:mode>"
@@ -7714,47 +7755,81 @@ (define_insn "@pred_reduc_plus<order><VDF:mode><VDF_LMUL1:mode>"
   ]
)
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"             "=&vr,  &vr")
- (unspec:<VWLMUL1>
-   [(unspec:<VWLMUL1>
-     [(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")
-         (reg:SI VL_REGNUM)
-         (reg:SI VTYPE_REGNUM)
-         (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-      (match_operand:VWF 3 "register_operand"             "   vr,   vr")
-      (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-      (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+;; Float Widen Reduction for HF, aka SF = HF op SF
+(define_insn "@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VSF_LMUL1
+ [
+   (unspec:VSF_LMUL1
+     [
+       (unspec:<VHF:VM>
+ [
+   (match_operand:<VHF:VM> 1 "vector_merge_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")
+   (reg:SI VL_REGNUM)
+   (reg:SI VTYPE_REGNUM)
+   (reg:SI FRM_REGNUM)
+ ] UNSPEC_VPREDICATE
+       )
+       (match_operand:VHF          3 "register_operand"      "   vr,   vr")
+       (match_operand:VSF_LMUL1    4 "register_operand"      "   vr,   vr")
+       (match_operand:VSF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+     ] UNSPEC_WREDUC_SUM
+   )
+ ] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VHF:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"             "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE64>
-   [(unspec:<VWLMUL1_ZVE64>
-     [(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")
-         (reg:SI VL_REGNUM)
-         (reg:SI VTYPE_REGNUM)
-         (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-      (match_operand:VWF_ZVE64 3 "register_operand"             "   vr,   vr")
-      (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-      (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+;; Float Widen Reduction for SF, aka DF = SF * DF
+(define_insn "@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VDF_LMUL1
+ [
+   (unspec:VDF_LMUL1
+     [
+       (unspec:<VSF:VM>
+ [
+   (match_operand:<VSF:VM> 1 "vector_merge_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")
+   (reg:SI VL_REGNUM)
+   (reg:SI VTYPE_REGNUM)
+   (reg:SI FRM_REGNUM)
+ ] UNSPEC_VPREDICATE
+       )
+       (match_operand:VSF          3 "register_operand"      "   vr,   vr")
+       (match_operand:VDF_LMUL1    4 "register_operand"      "   vr,   vr")
+       (match_operand:VDF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+     ] UNSPEC_WREDUC_SUM
+   )
+ ] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VSF:MODE>")
+  ]
+)
;; -------------------------------------------------------------------------------
;; ---- Predicated permutation operations
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
new file mode 100644
index 00000000000..d83eea925a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
new file mode 100644
index 00000000000..a8ea018ccc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
@@ -0,0 +1,9 @@
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16m8_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16m8_f32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
new file mode 100644
index 00000000000..cdcde1b89a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+#include "pr110299-2.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
new file mode 100644
index 00000000000..51d4d4470d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredusum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f32m8_f64m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredosum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f32m8_f64m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
new file mode 100644
index 00000000000..0f84c17d6f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
new file mode 100644
index 00000000000..3416196b8cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf4_i16m1(vint8mf4_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf4_i16m1(vector, scalar, vl);
+}
+
+vint32m1_t test_vwredsum_vs_i16m8_i32m1(vint16m8_t vector, vint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i16m8_i32m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf4_u16m1(vuint8mf4_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf4_u16m1(vector, scalar, vl);
+}
+
+vuint32m1_t test_vwredsumu_vs_u16m8_u32m1(vuint16m8_t vector, vuint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u16m8_u32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
new file mode 100644
index 00000000000..8297cd62f65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+#include "pr110299-4.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
new file mode 100644
index 00000000000..b4f7d403fe3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf8_i16m1(vint8mf8_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf8_i16m1(vector, scalar, vl);
+}
+
+vint64m1_t test_vwredsum_vs_i32m8_i64m1(vint32m8_t vector, vint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i32m8_i64m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf8_u16m1(vuint8mf8_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf8_u16m1(vector, scalar, vl);
+}
+
+vuint64m1_t test_vwredsumu_vs_u32m8_u64m1(vuint32m8_t vector, vuint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u32m8_u64m1(vector, scalar, vl);
+}
-- 
2.34.1
  
Li, Pan2 via Gcc-patches June 19, 2023, 1:29 a.m. UTC | #2
Thanks Juzhe, will not send the V2 as only commit log change.

Pan

From: 钟居哲 <juzhe.zhong@rivai.ai>
Sent: Monday, June 19, 2023 6:02 AM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: rdapp.gcc <rdapp.gcc@gmail.com>; Jeff Law <jeffreyalaw@gmail.com>; Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64

Add target into changelog:
PR target/110299

Otherwise, LGTM.
________________________________
juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>

From: pan2.li<mailto:pan2.li@intel.com>
Date: 2023-06-18 23:13
To: gcc-patches<mailto:gcc-patches@gcc.gnu.org>
CC: juzhe.zhong<mailto:juzhe.zhong@rivai.ai>; rdapp.gcc<mailto:rdapp.gcc@gmail.com>; jeffreyalaw<mailto:jeffreyalaw@gmail.com>; pan2.li<mailto:pan2.li@intel.com>; yanzhang.wang<mailto:yanzhang.wang@intel.com>; kito.cheng<mailto:kito.cheng@gmail.com>
Subject: [PATCH v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64
From: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>

The rvv widdening reduction has 3 different patterns for zve128+, zve64
and zve32. They take the same iterator with different attributions.
However, we need the generated function code_for_reduc (code, mode1, mode2).
The implementation of code_for_reduc may look like below.

code_for_reduc (code, mode1, mode2)
{
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx16hf; // ZVE128+

  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx8hf;  // ZVE64

  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx4hf;  // ZVE32
}

Thus there will be a problem here. For example zve32, we will have
code_for_reduc (max, VNx1HF, VNx1HF) which will return the code of
the ZVE128+ instead of the ZVE32 logically.

This patch will merge the 3 patterns into pattern, and pass both the
input_vector and the ret_vector of code_for_reduc. For example, ZVE32
will be code_for_reduc (max, VNx1HF, VNx2HF), then the correct code of ZVE32
will be returned as expectation.

Please note both GCC 13 and 14 are impacted by this issue.

Signed-off-by: Pan Li <pan2.li@intel.com<mailto:pan2.li@intel.com>>
Co-Authored by: Juzhe-Zhong <juzhe.zhong@rivai.ai<mailto:juzhe.zhong@rivai.ai>>

PR 110299

gcc/ChangeLog:

* config/riscv/riscv-vector-builtins-bases.cc: Adjust expand for
modes.
* config/riscv/vector-iterators.md: Remove VWLMUL1, VWLMUL1_ZVE64,
VWLMUL1_ZVE32.
* config/riscv/vector.md
(@pred_widen_reduc_plus<v_su><mode><vwlmul1>): Removed.
(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>): Ditto.
(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>): Ditto.
(@pred_widen_reduc_plus<order><mode><vwlmul1>): Ditto.
(@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>): Ditto.
(@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>): New pattern.
(@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/pr110299-1.c: New test.
* gcc.target/riscv/rvv/base/pr110299-1.h: New test.
* gcc.target/riscv/rvv/base/pr110299-2.c: New test.
* gcc.target/riscv/rvv/base/pr110299-2.h: New test.
* gcc.target/riscv/rvv/base/pr110299-3.c: New test.
* gcc.target/riscv/rvv/base/pr110299-3.h: New test.
* gcc.target/riscv/rvv/base/pr110299-4.c: New test.
* gcc.target/riscv/rvv/base/pr110299-4.h: New test.
---
.../riscv/riscv-vector-builtins-bases.cc      |  16 +-
gcc/config/riscv/vector-iterators.md          |  62 -----
gcc/config/riscv/vector.md                    | 243 ++++++++++++------
.../gcc.target/riscv/rvv/base/pr110299-1.c    |   7 +
.../gcc.target/riscv/rvv/base/pr110299-1.h    |   9 +
.../gcc.target/riscv/rvv/base/pr110299-2.c    |   8 +
.../gcc.target/riscv/rvv/base/pr110299-2.h    |  17 ++
.../gcc.target/riscv/rvv/base/pr110299-3.c    |   7 +
.../gcc.target/riscv/rvv/base/pr110299-3.h    |  17 ++
.../gcc.target/riscv/rvv/base/pr110299-4.c    |   8 +
.../gcc.target/riscv/rvv/base/pr110299-4.h    |  17 ++
11 files changed, 253 insertions(+), 158 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h

diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 27545113996..c6c53dc13a5 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -1396,16 +1396,8 @@ public:
   rtx expand (function_expander &e) const override
   {
-    machine_mode mode = e.vector_mode ();
-    machine_mode ret_mode = e.ret_mode ();
-
-    /* TODO: we will use ret_mode after all types of PR110265 are addressed.  */
-    if (GET_MODE_INNER (mode) != GET_MODE_INNER (ret_mode))
-      return e.use_exact_insn (
- code_for_pred_reduc (CODE, e.vector_mode (), e.vector_mode ()));
-    else
-      return e.use_exact_insn (
- code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
+    return e.use_exact_insn (
+      code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
   }
};
@@ -1420,7 +1412,7 @@ public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
     e.vector_mode (),
-      e.vector_mode ()));
+      e.ret_mode ()));
   }
};
@@ -1449,7 +1441,7 @@ public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
     e.vector_mode (),
-      e.vector_mode ()));
+      e.ret_mode ()));
   }
};
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 6169116482a..e4c6c1bb135 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1392,68 +1392,6 @@ (define_mode_attr VNCONVERT [
   (VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI") (VNx16DF "VNx16SI")
])
-(define_mode_attr VWLMUL1 [
-  (VNx1QI "VNx8HI") (VNx2QI "VNx8HI") (VNx4QI "VNx8HI")
-  (VNx8QI "VNx8HI") (VNx16QI "VNx8HI") (VNx32QI "VNx8HI") (VNx64QI "VNx8HI") (VNx128QI "VNx8HI")
-  (VNx1HI "VNx4SI") (VNx2HI "VNx4SI") (VNx4HI "VNx4SI")
-  (VNx8HI "VNx4SI") (VNx16HI "VNx4SI") (VNx32HI "VNx4SI") (VNx64HI "VNx4SI")
-  (VNx1SI "VNx2DI") (VNx2SI "VNx2DI") (VNx4SI "VNx2DI")
-  (VNx8SI "VNx2DI") (VNx16SI "VNx2DI") (VNx32SI "VNx2DI")
-  (VNx1HF "VNx4SF") (VNx2HF "VNx4SF") (VNx4HF "VNx4SF") (VNx8HF "VNx4SF") (VNx16HF "VNx4SF") (VNx32HF "VNx4SF") (VNx64HF "VNx4SF")
-  (VNx1SF "VNx2DF") (VNx2SF "VNx2DF")
-  (VNx4SF "VNx2DF") (VNx8SF "VNx2DF") (VNx16SF "VNx2DF") (VNx32SF "VNx2DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE64 [
-  (VNx1QI "VNx4HI") (VNx2QI "VNx4HI") (VNx4QI "VNx4HI")
-  (VNx8QI "VNx4HI") (VNx16QI "VNx4HI") (VNx32QI "VNx4HI") (VNx64QI "VNx4HI")
-  (VNx1HI "VNx2SI") (VNx2HI "VNx2SI") (VNx4HI "VNx2SI")
-  (VNx8HI "VNx2SI") (VNx16HI "VNx2SI") (VNx32HI "VNx2SI")
-  (VNx1SI "VNx1DI") (VNx2SI "VNx1DI") (VNx4SI "VNx1DI")
-  (VNx8SI "VNx1DI") (VNx16SI "VNx1DI")
-  (VNx1HF "VNx2SF") (VNx2HF "VNx2SF") (VNx4HF "VNx2SF") (VNx8HF "VNx2SF") (VNx16HF "VNx2SF") (VNx32HF "VNx2SF")
-  (VNx1SF "VNx1DF") (VNx2SF "VNx1DF")
-  (VNx4SF "VNx1DF") (VNx8SF "VNx1DF") (VNx16SF "VNx1DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE32 [
-  (VNx1QI "VNx2HI") (VNx2QI "VNx2HI") (VNx4QI "VNx2HI")
-  (VNx8QI "VNx2HI") (VNx16QI "VNx2HI") (VNx32QI "VNx2HI")
-  (VNx1HI "VNx1SI") (VNx2HI "VNx1SI") (VNx4HI "VNx1SI")
-  (VNx8HI "VNx1SI") (VNx16HI "VNx1SI")
-])
-
-(define_mode_attr vwlmul1 [
-  (VNx1QI "vnx8hi") (VNx2QI "vnx8hi") (VNx4QI "vnx8hi")
-  (VNx8QI "vnx8hi") (VNx16QI "vnx8hi") (VNx32QI "vnx8hi") (VNx64QI "vnx8hi") (VNx128QI "vnx8hi")
-  (VNx1HI "vnx4si") (VNx2HI "vnx4si") (VNx4HI "vnx4si")
-  (VNx8HI "vnx4si") (VNx16HI "vnx4si") (VNx32HI "vnx4si") (VNx64HI "vnx4si")
-  (VNx1SI "vnx2di") (VNx2SI "vnx2di") (VNx4SI "vnx2di")
-  (VNx8SI "vnx2di") (VNx16SI "vnx2di") (VNx32SI "vnx2di")
-  (VNx1HF "vnx4sf") (VNx2HF "vnx4sf") (VNx4HF "vnx4sf") (VNx8HF "vnx4sf") (VNx16HF "vnx4sf") (VNx32HF "vnx4sf") (VNx64HF "vnx4sf")
-  (VNx1SF "vnx2df") (VNx2SF "vnx2df")
-  (VNx4SF "vnx2df") (VNx8SF "vnx2df") (VNx16SF "vnx2df") (VNx32SF "vnx2df")
-])
-
-(define_mode_attr vwlmul1_zve64 [
-  (VNx1QI "vnx4hi") (VNx2QI "vnx4hi") (VNx4QI "vnx4hi")
-  (VNx8QI "vnx4hi") (VNx16QI "vnx4hi") (VNx32QI "vnx4hi") (VNx64QI "vnx4hi")
-  (VNx1HI "vnx2si") (VNx2HI "vnx2si") (VNx4HI "vnx2si")
-  (VNx8HI "vnx2si") (VNx16HI "vnx2si") (VNx32HI "vnx2si")
-  (VNx1SI "vnx1di") (VNx2SI "vnx1di") (VNx4SI "vnx1di")
-  (VNx8SI "vnx1di") (VNx16SI "vnx1di")
-  (VNx1HF "vnx2sf") (VNx2HF "vnx2sf") (VNx4HF "vnx2sf") (VNx8HF "vnx2sf") (VNx16HF "vnx2sf") (VNx32HF "vnx2sf")
-  (VNx1SF "vnx1df") (VNx2SF "vnx1df")
-  (VNx4SF "vnx1df") (VNx8SF "vnx1df") (VNx16SF "vnx1df")
-])
-
-(define_mode_attr vwlmul1_zve32 [
-  (VNx1QI "vnx2hi") (VNx2QI "vnx2hi") (VNx4QI "vnx2hi")
-  (VNx8QI "vnx2hi") (VNx16QI "vnx2hi") (VNx32QI "vnx2hi")
-  (VNx1HI "vnx1si") (VNx2HI "vnx1si") (VNx4HI "vnx1si")
-  (VNx8HI "vnx1si") (VNx16HI "vnx1si")
-])
-
(define_mode_attr VDEMOTE [
   (VNx1DI "VNx2SI") (VNx2DI "VNx4SI")
   (VNx4DI "VNx8SI") (VNx8DI "VNx16SI") (VNx16DI "VNx32SI")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index efce992a012..884e7435cc2 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -7407,60 +7407,101 @@ (define_insn "@pred_reduc_<reduc><VDI:mode><VDI_LMUL1:mode>"
   ]
)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1>
-   [(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")
+;; Integer Reduction Widen for QI, HI = QI op HI
+(define_insn "@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VHI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VHI_LMUL1
+ [
+   (unspec:<VQI:VM>
+     [
+       (match_operand:<VQI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VQI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VHI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VHI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VQI:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE64>
-   [(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")
+;; Integer Reduction Widen for HI, SI = HI op SI
+(define_insn "@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VSI_LMUL1
+ [
+   (unspec:<VHI:VM>
+     [
+       (match_operand:<VHI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI_ZVE64 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VHI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VSI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VSI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
-
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VHI:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>"
-  [(set (match_operand:<VWLMUL1_ZVE32> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE32>
-   [(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")
+;; Integer Reduction Widen for SI, DI = SI op DI
+(define_insn "@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VDI_LMUL1
+ [
+   (unspec:<VSI:VM>
+     [
+       (match_operand:<VSI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI_ZVE32 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE32> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE32> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VSI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VDI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VDI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VSI:MODE>")
+  ]
+)
;; Float Reduction for HF
(define_insn "@pred_reduc_<reduc><VHF:mode><VHF_LMUL1:mode>"
@@ -7714,47 +7755,81 @@ (define_insn "@pred_reduc_plus<order><VDF:mode><VDF_LMUL1:mode>"
   ]
)
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"             "=&vr,  &vr")
- (unspec:<VWLMUL1>
-   [(unspec:<VWLMUL1>
-     [(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")
-         (reg:SI VL_REGNUM)
-         (reg:SI VTYPE_REGNUM)
-         (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-      (match_operand:VWF 3 "register_operand"             "   vr,   vr")
-      (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-      (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+;; Float Widen Reduction for HF, aka SF = HF op SF
+(define_insn "@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VSF_LMUL1
+ [
+   (unspec:VSF_LMUL1
+     [
+       (unspec:<VHF:VM>
+ [
+   (match_operand:<VHF:VM> 1 "vector_merge_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")
+   (reg:SI VL_REGNUM)
+   (reg:SI VTYPE_REGNUM)
+   (reg:SI FRM_REGNUM)
+ ] UNSPEC_VPREDICATE
+       )
+       (match_operand:VHF          3 "register_operand"      "   vr,   vr")
+       (match_operand:VSF_LMUL1    4 "register_operand"      "   vr,   vr")
+       (match_operand:VSF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+     ] UNSPEC_WREDUC_SUM
+   )
+ ] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VHF:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"             "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE64>
-   [(unspec:<VWLMUL1_ZVE64>
-     [(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")
-         (reg:SI VL_REGNUM)
-         (reg:SI VTYPE_REGNUM)
-         (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-      (match_operand:VWF_ZVE64 3 "register_operand"             "   vr,   vr")
-      (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-      (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+;; Float Widen Reduction for SF, aka DF = SF * DF
+(define_insn "@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VDF_LMUL1
+ [
+   (unspec:VDF_LMUL1
+     [
+       (unspec:<VSF:VM>
+ [
+   (match_operand:<VSF:VM> 1 "vector_merge_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")
+   (reg:SI VL_REGNUM)
+   (reg:SI VTYPE_REGNUM)
+   (reg:SI FRM_REGNUM)
+ ] UNSPEC_VPREDICATE
+       )
+       (match_operand:VSF          3 "register_operand"      "   vr,   vr")
+       (match_operand:VDF_LMUL1    4 "register_operand"      "   vr,   vr")
+       (match_operand:VDF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+     ] UNSPEC_WREDUC_SUM
+   )
+ ] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VSF:MODE>")
+  ]
+)
;; -------------------------------------------------------------------------------
;; ---- Predicated permutation operations
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
new file mode 100644
index 00000000000..d83eea925a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
new file mode 100644
index 00000000000..a8ea018ccc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
@@ -0,0 +1,9 @@
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16m8_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16m8_f32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
new file mode 100644
index 00000000000..cdcde1b89a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+#include "pr110299-2.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
new file mode 100644
index 00000000000..51d4d4470d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredusum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f32m8_f64m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredosum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f32m8_f64m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
new file mode 100644
index 00000000000..0f84c17d6f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
new file mode 100644
index 00000000000..3416196b8cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf4_i16m1(vint8mf4_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf4_i16m1(vector, scalar, vl);
+}
+
+vint32m1_t test_vwredsum_vs_i16m8_i32m1(vint16m8_t vector, vint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i16m8_i32m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf4_u16m1(vuint8mf4_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf4_u16m1(vector, scalar, vl);
+}
+
+vuint32m1_t test_vwredsumu_vs_u16m8_u32m1(vuint16m8_t vector, vuint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u16m8_u32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
new file mode 100644
index 00000000000..8297cd62f65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+#include "pr110299-4.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
new file mode 100644
index 00000000000..b4f7d403fe3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf8_i16m1(vint8mf8_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf8_i16m1(vector, scalar, vl);
+}
+
+vint64m1_t test_vwredsum_vs_i32m8_i64m1(vint32m8_t vector, vint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i32m8_i64m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf8_u16m1(vuint8mf8_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf8_u16m1(vector, scalar, vl);
+}
+
+vuint64m1_t test_vwredsumu_vs_u32m8_u64m1(vuint32m8_t vector, vuint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u32m8_u64m1(vector, scalar, vl);
+}
--
2.34.1
  
juzhe.zhong@rivai.ai June 19, 2023, 4:40 a.m. UTC | #3
I notice VWF_ZVE64 
should be removed.


juzhe.zhong@rivai.ai
 
From: Li, Pan2
Date: 2023-06-19 09:29
To: 钟居哲; gcc-patches
CC: rdapp.gcc; Jeff Law; Wang, Yanzhang; kito.cheng
Subject: RE: [PATCH v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64
Thanks Juzhe, will not send the V2 as only commit log change.
 
Pan
 
From: 钟居哲 <juzhe.zhong@rivai.ai> 
Sent: Monday, June 19, 2023 6:02 AM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches <gcc-patches@gcc.gnu.org>
Cc: rdapp.gcc <rdapp.gcc@gmail.com>; Jeff Law <jeffreyalaw@gmail.com>; Li, Pan2 <pan2.li@intel.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; kito.cheng <kito.cheng@gmail.com>
Subject: Re: [PATCH v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64
 
Add target into changelog:
PR target/110299
 
Otherwise, LGTM.


juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2023-06-18 23:13
To: gcc-patches
CC: juzhe.zhong; rdapp.gcc; jeffreyalaw; pan2.li; yanzhang.wang; kito.cheng
Subject: [PATCH v1] RISC-V: Bugfix for RVV widenning reduction in ZVE32/64
From: Pan Li <pan2.li@intel.com>
 
The rvv widdening reduction has 3 different patterns for zve128+, zve64
and zve32. They take the same iterator with different attributions.
However, we need the generated function code_for_reduc (code, mode1, mode2).
The implementation of code_for_reduc may look like below.
 
code_for_reduc (code, mode1, mode2)
{
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx16hf; // ZVE128+
 
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx8hf;  // ZVE64
 
  if (code == max && mode1 == VNx1HF && mode2 == VNx1HF)
    return CODE_FOR_pred_reduc_maxvnx1hfvnx4hf;  // ZVE32
}
 
Thus there will be a problem here. For example zve32, we will have
code_for_reduc (max, VNx1HF, VNx1HF) which will return the code of
the ZVE128+ instead of the ZVE32 logically.
 
This patch will merge the 3 patterns into pattern, and pass both the
input_vector and the ret_vector of code_for_reduc. For example, ZVE32
will be code_for_reduc (max, VNx1HF, VNx2HF), then the correct code of ZVE32
will be returned as expectation.
 
Please note both GCC 13 and 14 are impacted by this issue.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
Co-Authored by: Juzhe-Zhong <juzhe.zhong@rivai.ai>
 
PR 110299
 
gcc/ChangeLog:
 
* config/riscv/riscv-vector-builtins-bases.cc: Adjust expand for
modes.
* config/riscv/vector-iterators.md: Remove VWLMUL1, VWLMUL1_ZVE64,
VWLMUL1_ZVE32.
* config/riscv/vector.md
(@pred_widen_reduc_plus<v_su><mode><vwlmul1>): Removed.
(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>): Ditto.
(@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>): Ditto.
(@pred_widen_reduc_plus<order><mode><vwlmul1>): Ditto.
(@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>): Ditto.
(@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>): New pattern.
(@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>): Ditto.
(@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>): Ditto.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/pr110299-1.c: New test.
* gcc.target/riscv/rvv/base/pr110299-1.h: New test.
* gcc.target/riscv/rvv/base/pr110299-2.c: New test.
* gcc.target/riscv/rvv/base/pr110299-2.h: New test.
* gcc.target/riscv/rvv/base/pr110299-3.c: New test.
* gcc.target/riscv/rvv/base/pr110299-3.h: New test.
* gcc.target/riscv/rvv/base/pr110299-4.c: New test.
* gcc.target/riscv/rvv/base/pr110299-4.h: New test.
---
.../riscv/riscv-vector-builtins-bases.cc      |  16 +-
gcc/config/riscv/vector-iterators.md          |  62 -----
gcc/config/riscv/vector.md                    | 243 ++++++++++++------
.../gcc.target/riscv/rvv/base/pr110299-1.c    |   7 +
.../gcc.target/riscv/rvv/base/pr110299-1.h    |   9 +
.../gcc.target/riscv/rvv/base/pr110299-2.c    |   8 +
.../gcc.target/riscv/rvv/base/pr110299-2.h    |  17 ++
.../gcc.target/riscv/rvv/base/pr110299-3.c    |   7 +
.../gcc.target/riscv/rvv/base/pr110299-3.h    |  17 ++
.../gcc.target/riscv/rvv/base/pr110299-4.c    |   8 +
.../gcc.target/riscv/rvv/base/pr110299-4.h    |  17 ++
11 files changed, 253 insertions(+), 158 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
 
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 27545113996..c6c53dc13a5 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -1396,16 +1396,8 @@ public:
   rtx expand (function_expander &e) const override
   {
-    machine_mode mode = e.vector_mode ();
-    machine_mode ret_mode = e.ret_mode ();
-
-    /* TODO: we will use ret_mode after all types of PR110265 are addressed.  */
-    if (GET_MODE_INNER (mode) != GET_MODE_INNER (ret_mode))
-      return e.use_exact_insn (
- code_for_pred_reduc (CODE, e.vector_mode (), e.vector_mode ()));
-    else
-      return e.use_exact_insn (
- code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
+    return e.use_exact_insn (
+      code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
   }
};
@@ -1420,7 +1412,7 @@ public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
     e.vector_mode (),
-      e.vector_mode ()));
+      e.ret_mode ()));
   }
};
@@ -1449,7 +1441,7 @@ public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
     e.vector_mode (),
-      e.vector_mode ()));
+      e.ret_mode ()));
   }
};
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 6169116482a..e4c6c1bb135 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1392,68 +1392,6 @@ (define_mode_attr VNCONVERT [
   (VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI") (VNx16DF "VNx16SI")
])
-(define_mode_attr VWLMUL1 [
-  (VNx1QI "VNx8HI") (VNx2QI "VNx8HI") (VNx4QI "VNx8HI")
-  (VNx8QI "VNx8HI") (VNx16QI "VNx8HI") (VNx32QI "VNx8HI") (VNx64QI "VNx8HI") (VNx128QI "VNx8HI")
-  (VNx1HI "VNx4SI") (VNx2HI "VNx4SI") (VNx4HI "VNx4SI")
-  (VNx8HI "VNx4SI") (VNx16HI "VNx4SI") (VNx32HI "VNx4SI") (VNx64HI "VNx4SI")
-  (VNx1SI "VNx2DI") (VNx2SI "VNx2DI") (VNx4SI "VNx2DI")
-  (VNx8SI "VNx2DI") (VNx16SI "VNx2DI") (VNx32SI "VNx2DI")
-  (VNx1HF "VNx4SF") (VNx2HF "VNx4SF") (VNx4HF "VNx4SF") (VNx8HF "VNx4SF") (VNx16HF "VNx4SF") (VNx32HF "VNx4SF") (VNx64HF "VNx4SF")
-  (VNx1SF "VNx2DF") (VNx2SF "VNx2DF")
-  (VNx4SF "VNx2DF") (VNx8SF "VNx2DF") (VNx16SF "VNx2DF") (VNx32SF "VNx2DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE64 [
-  (VNx1QI "VNx4HI") (VNx2QI "VNx4HI") (VNx4QI "VNx4HI")
-  (VNx8QI "VNx4HI") (VNx16QI "VNx4HI") (VNx32QI "VNx4HI") (VNx64QI "VNx4HI")
-  (VNx1HI "VNx2SI") (VNx2HI "VNx2SI") (VNx4HI "VNx2SI")
-  (VNx8HI "VNx2SI") (VNx16HI "VNx2SI") (VNx32HI "VNx2SI")
-  (VNx1SI "VNx1DI") (VNx2SI "VNx1DI") (VNx4SI "VNx1DI")
-  (VNx8SI "VNx1DI") (VNx16SI "VNx1DI")
-  (VNx1HF "VNx2SF") (VNx2HF "VNx2SF") (VNx4HF "VNx2SF") (VNx8HF "VNx2SF") (VNx16HF "VNx2SF") (VNx32HF "VNx2SF")
-  (VNx1SF "VNx1DF") (VNx2SF "VNx1DF")
-  (VNx4SF "VNx1DF") (VNx8SF "VNx1DF") (VNx16SF "VNx1DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE32 [
-  (VNx1QI "VNx2HI") (VNx2QI "VNx2HI") (VNx4QI "VNx2HI")
-  (VNx8QI "VNx2HI") (VNx16QI "VNx2HI") (VNx32QI "VNx2HI")
-  (VNx1HI "VNx1SI") (VNx2HI "VNx1SI") (VNx4HI "VNx1SI")
-  (VNx8HI "VNx1SI") (VNx16HI "VNx1SI")
-])
-
-(define_mode_attr vwlmul1 [
-  (VNx1QI "vnx8hi") (VNx2QI "vnx8hi") (VNx4QI "vnx8hi")
-  (VNx8QI "vnx8hi") (VNx16QI "vnx8hi") (VNx32QI "vnx8hi") (VNx64QI "vnx8hi") (VNx128QI "vnx8hi")
-  (VNx1HI "vnx4si") (VNx2HI "vnx4si") (VNx4HI "vnx4si")
-  (VNx8HI "vnx4si") (VNx16HI "vnx4si") (VNx32HI "vnx4si") (VNx64HI "vnx4si")
-  (VNx1SI "vnx2di") (VNx2SI "vnx2di") (VNx4SI "vnx2di")
-  (VNx8SI "vnx2di") (VNx16SI "vnx2di") (VNx32SI "vnx2di")
-  (VNx1HF "vnx4sf") (VNx2HF "vnx4sf") (VNx4HF "vnx4sf") (VNx8HF "vnx4sf") (VNx16HF "vnx4sf") (VNx32HF "vnx4sf") (VNx64HF "vnx4sf")
-  (VNx1SF "vnx2df") (VNx2SF "vnx2df")
-  (VNx4SF "vnx2df") (VNx8SF "vnx2df") (VNx16SF "vnx2df") (VNx32SF "vnx2df")
-])
-
-(define_mode_attr vwlmul1_zve64 [
-  (VNx1QI "vnx4hi") (VNx2QI "vnx4hi") (VNx4QI "vnx4hi")
-  (VNx8QI "vnx4hi") (VNx16QI "vnx4hi") (VNx32QI "vnx4hi") (VNx64QI "vnx4hi")
-  (VNx1HI "vnx2si") (VNx2HI "vnx2si") (VNx4HI "vnx2si")
-  (VNx8HI "vnx2si") (VNx16HI "vnx2si") (VNx32HI "vnx2si")
-  (VNx1SI "vnx1di") (VNx2SI "vnx1di") (VNx4SI "vnx1di")
-  (VNx8SI "vnx1di") (VNx16SI "vnx1di")
-  (VNx1HF "vnx2sf") (VNx2HF "vnx2sf") (VNx4HF "vnx2sf") (VNx8HF "vnx2sf") (VNx16HF "vnx2sf") (VNx32HF "vnx2sf")
-  (VNx1SF "vnx1df") (VNx2SF "vnx1df")
-  (VNx4SF "vnx1df") (VNx8SF "vnx1df") (VNx16SF "vnx1df")
-])
-
-(define_mode_attr vwlmul1_zve32 [
-  (VNx1QI "vnx2hi") (VNx2QI "vnx2hi") (VNx4QI "vnx2hi")
-  (VNx8QI "vnx2hi") (VNx16QI "vnx2hi") (VNx32QI "vnx2hi")
-  (VNx1HI "vnx1si") (VNx2HI "vnx1si") (VNx4HI "vnx1si")
-  (VNx8HI "vnx1si") (VNx16HI "vnx1si")
-])
-
(define_mode_attr VDEMOTE [
   (VNx1DI "VNx2SI") (VNx2DI "VNx4SI")
   (VNx4DI "VNx8SI") (VNx8DI "VNx16SI") (VNx16DI "VNx32SI")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index efce992a012..884e7435cc2 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -7407,60 +7407,101 @@ (define_insn "@pred_reduc_<reduc><VDI:mode><VDI_LMUL1:mode>"
   ]
)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1>
-   [(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")
+;; Integer Reduction Widen for QI, HI = QI op HI
+(define_insn "@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VHI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VHI_LMUL1
+ [
+   (unspec:<VQI:VM>
+     [
+       (match_operand:<VQI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VQI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VHI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VHI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VQI:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE64>
-   [(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")
+;; Integer Reduction Widen for HI, SI = HI op SI
+(define_insn "@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VSI_LMUL1
+ [
+   (unspec:<VHI:VM>
+     [
+       (match_operand:<VHI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI_ZVE64 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VHI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VSI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VSI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
-
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VHI:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>"
-  [(set (match_operand:<VWLMUL1_ZVE32> 0 "register_operand"           "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE32>
-   [(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")
+;; Integer Reduction Widen for SI, DI = SI op DI
+(define_insn "@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VDI_LMUL1
+ [
+   (unspec:<VSI:VM>
+     [
+       (match_operand:<VSI: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")
      (reg:SI VL_REGNUM)
-       (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-    (match_operand:VWI_ZVE32 3 "register_operand"             "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE32> 4 "register_operand"       "   vr,   vr")
-    (match_operand:<VWLMUL1_ZVE32> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+       (reg:SI VTYPE_REGNUM)
+     ] UNSPEC_VPREDICATE
+   )
+   (match_operand:VSI          3 "register_operand"      "   vr,   vr")
+   (match_operand:VDI_LMUL1    4 "register_operand"      "   vr,   vr")
+   (match_operand:VDI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+ ] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VSI:MODE>")
+  ]
+)
;; Float Reduction for HF
(define_insn "@pred_reduc_<reduc><VHF:mode><VHF_LMUL1:mode>"
@@ -7714,47 +7755,81 @@ (define_insn "@pred_reduc_plus<order><VDF:mode><VDF_LMUL1:mode>"
   ]
)
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"             "=&vr,  &vr")
- (unspec:<VWLMUL1>
-   [(unspec:<VWLMUL1>
-     [(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")
-         (reg:SI VL_REGNUM)
-         (reg:SI VTYPE_REGNUM)
-         (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-      (match_operand:VWF 3 "register_operand"             "   vr,   vr")
-      (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-      (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+;; Float Widen Reduction for HF, aka SF = HF op SF
+(define_insn "@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VSF_LMUL1
+ [
+   (unspec:VSF_LMUL1
+     [
+       (unspec:<VHF:VM>
+ [
+   (match_operand:<VHF:VM> 1 "vector_merge_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")
+   (reg:SI VL_REGNUM)
+   (reg:SI VTYPE_REGNUM)
+   (reg:SI FRM_REGNUM)
+ ] UNSPEC_VPREDICATE
+       )
+       (match_operand:VHF          3 "register_operand"      "   vr,   vr")
+       (match_operand:VSF_LMUL1    4 "register_operand"      "   vr,   vr")
+       (match_operand:VSF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+     ] UNSPEC_WREDUC_SUM
+   )
+ ] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VHF:MODE>")
+  ]
+)
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"             "=&vr,  &vr")
- (unspec:<VWLMUL1_ZVE64>
-   [(unspec:<VWLMUL1_ZVE64>
-     [(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")
-         (reg:SI VL_REGNUM)
-         (reg:SI VTYPE_REGNUM)
-         (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-      (match_operand:VWF_ZVE64 3 "register_operand"             "   vr,   vr")
-      (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-      (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+;; Float Widen Reduction for SF, aka DF = SF * DF
+(define_insn "@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VDF_LMUL1
+ [
+   (unspec:VDF_LMUL1
+     [
+       (unspec:<VSF:VM>
+ [
+   (match_operand:<VSF:VM> 1 "vector_merge_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")
+   (reg:SI VL_REGNUM)
+   (reg:SI VTYPE_REGNUM)
+   (reg:SI FRM_REGNUM)
+ ] UNSPEC_VPREDICATE
+       )
+       (match_operand:VSF          3 "register_operand"      "   vr,   vr")
+       (match_operand:VDF_LMUL1    4 "register_operand"      "   vr,   vr")
+       (match_operand:VDF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+     ] UNSPEC_WREDUC_SUM
+   )
+ ] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VSF:MODE>")
+  ]
+)
;; -------------------------------------------------------------------------------
;; ---- Predicated permutation operations
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
new file mode 100644
index 00000000000..d83eea925a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
new file mode 100644
index 00000000000..a8ea018ccc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
@@ -0,0 +1,9 @@
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16m8_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16m8_f32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
new file mode 100644
index 00000000000..cdcde1b89a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+#include "pr110299-2.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
new file mode 100644
index 00000000000..51d4d4470d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredusum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f32m8_f64m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredosum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f32m8_f64m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
new file mode 100644
index 00000000000..0f84c17d6f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
new file mode 100644
index 00000000000..3416196b8cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf4_i16m1(vint8mf4_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf4_i16m1(vector, scalar, vl);
+}
+
+vint32m1_t test_vwredsum_vs_i16m8_i32m1(vint16m8_t vector, vint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i16m8_i32m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf4_u16m1(vuint8mf4_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf4_u16m1(vector, scalar, vl);
+}
+
+vuint32m1_t test_vwredsumu_vs_u16m8_u32m1(vuint16m8_t vector, vuint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u16m8_u32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
new file mode 100644
index 00000000000..8297cd62f65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+#include "pr110299-4.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
new file mode 100644
index 00000000000..b4f7d403fe3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
@@ -0,0 +1,17 @@
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf8_i16m1(vint8mf8_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf8_i16m1(vector, scalar, vl);
+}
+
+vint64m1_t test_vwredsum_vs_i32m8_i64m1(vint32m8_t vector, vint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i32m8_i64m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf8_u16m1(vuint8mf8_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf8_u16m1(vector, scalar, vl);
+}
+
+vuint64m1_t test_vwredsumu_vs_u32m8_u64m1(vuint32m8_t vector, vuint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u32m8_u64m1(vector, scalar, vl);
+}
-- 
2.34.1
  

Patch

diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 27545113996..c6c53dc13a5 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -1396,16 +1396,8 @@  public:
 
   rtx expand (function_expander &e) const override
   {
-    machine_mode mode = e.vector_mode ();
-    machine_mode ret_mode = e.ret_mode ();
-
-    /* TODO: we will use ret_mode after all types of PR110265 are addressed.  */
-    if (GET_MODE_INNER (mode) != GET_MODE_INNER (ret_mode))
-      return e.use_exact_insn (
-	code_for_pred_reduc (CODE, e.vector_mode (), e.vector_mode ()));
-    else
-      return e.use_exact_insn (
-	code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
+    return e.use_exact_insn (
+      code_for_pred_reduc (CODE, e.vector_mode (), e.ret_mode ()));
   }
 };
 
@@ -1420,7 +1412,7 @@  public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
 							     e.vector_mode (),
-							     e.vector_mode ()));
+							     e.ret_mode ()));
   }
 };
 
@@ -1449,7 +1441,7 @@  public:
   {
     return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
 							     e.vector_mode (),
-							     e.vector_mode ()));
+							     e.ret_mode ()));
   }
 };
 
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 6169116482a..e4c6c1bb135 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -1392,68 +1392,6 @@  (define_mode_attr VNCONVERT [
   (VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI") (VNx16DF "VNx16SI")
 ])
 
-(define_mode_attr VWLMUL1 [
-  (VNx1QI "VNx8HI") (VNx2QI "VNx8HI") (VNx4QI "VNx8HI")
-  (VNx8QI "VNx8HI") (VNx16QI "VNx8HI") (VNx32QI "VNx8HI") (VNx64QI "VNx8HI") (VNx128QI "VNx8HI")
-  (VNx1HI "VNx4SI") (VNx2HI "VNx4SI") (VNx4HI "VNx4SI")
-  (VNx8HI "VNx4SI") (VNx16HI "VNx4SI") (VNx32HI "VNx4SI") (VNx64HI "VNx4SI")
-  (VNx1SI "VNx2DI") (VNx2SI "VNx2DI") (VNx4SI "VNx2DI")
-  (VNx8SI "VNx2DI") (VNx16SI "VNx2DI") (VNx32SI "VNx2DI")
-  (VNx1HF "VNx4SF") (VNx2HF "VNx4SF") (VNx4HF "VNx4SF") (VNx8HF "VNx4SF") (VNx16HF "VNx4SF") (VNx32HF "VNx4SF") (VNx64HF "VNx4SF")
-  (VNx1SF "VNx2DF") (VNx2SF "VNx2DF")
-  (VNx4SF "VNx2DF") (VNx8SF "VNx2DF") (VNx16SF "VNx2DF") (VNx32SF "VNx2DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE64 [
-  (VNx1QI "VNx4HI") (VNx2QI "VNx4HI") (VNx4QI "VNx4HI")
-  (VNx8QI "VNx4HI") (VNx16QI "VNx4HI") (VNx32QI "VNx4HI") (VNx64QI "VNx4HI")
-  (VNx1HI "VNx2SI") (VNx2HI "VNx2SI") (VNx4HI "VNx2SI")
-  (VNx8HI "VNx2SI") (VNx16HI "VNx2SI") (VNx32HI "VNx2SI")
-  (VNx1SI "VNx1DI") (VNx2SI "VNx1DI") (VNx4SI "VNx1DI")
-  (VNx8SI "VNx1DI") (VNx16SI "VNx1DI")
-  (VNx1HF "VNx2SF") (VNx2HF "VNx2SF") (VNx4HF "VNx2SF") (VNx8HF "VNx2SF") (VNx16HF "VNx2SF") (VNx32HF "VNx2SF")
-  (VNx1SF "VNx1DF") (VNx2SF "VNx1DF")
-  (VNx4SF "VNx1DF") (VNx8SF "VNx1DF") (VNx16SF "VNx1DF")
-])
-
-(define_mode_attr VWLMUL1_ZVE32 [
-  (VNx1QI "VNx2HI") (VNx2QI "VNx2HI") (VNx4QI "VNx2HI")
-  (VNx8QI "VNx2HI") (VNx16QI "VNx2HI") (VNx32QI "VNx2HI")
-  (VNx1HI "VNx1SI") (VNx2HI "VNx1SI") (VNx4HI "VNx1SI")
-  (VNx8HI "VNx1SI") (VNx16HI "VNx1SI")
-])
-
-(define_mode_attr vwlmul1 [
-  (VNx1QI "vnx8hi") (VNx2QI "vnx8hi") (VNx4QI "vnx8hi")
-  (VNx8QI "vnx8hi") (VNx16QI "vnx8hi") (VNx32QI "vnx8hi") (VNx64QI "vnx8hi") (VNx128QI "vnx8hi")
-  (VNx1HI "vnx4si") (VNx2HI "vnx4si") (VNx4HI "vnx4si")
-  (VNx8HI "vnx4si") (VNx16HI "vnx4si") (VNx32HI "vnx4si") (VNx64HI "vnx4si")
-  (VNx1SI "vnx2di") (VNx2SI "vnx2di") (VNx4SI "vnx2di")
-  (VNx8SI "vnx2di") (VNx16SI "vnx2di") (VNx32SI "vnx2di")
-  (VNx1HF "vnx4sf") (VNx2HF "vnx4sf") (VNx4HF "vnx4sf") (VNx8HF "vnx4sf") (VNx16HF "vnx4sf") (VNx32HF "vnx4sf") (VNx64HF "vnx4sf")
-  (VNx1SF "vnx2df") (VNx2SF "vnx2df")
-  (VNx4SF "vnx2df") (VNx8SF "vnx2df") (VNx16SF "vnx2df") (VNx32SF "vnx2df")
-])
-
-(define_mode_attr vwlmul1_zve64 [
-  (VNx1QI "vnx4hi") (VNx2QI "vnx4hi") (VNx4QI "vnx4hi")
-  (VNx8QI "vnx4hi") (VNx16QI "vnx4hi") (VNx32QI "vnx4hi") (VNx64QI "vnx4hi")
-  (VNx1HI "vnx2si") (VNx2HI "vnx2si") (VNx4HI "vnx2si")
-  (VNx8HI "vnx2si") (VNx16HI "vnx2si") (VNx32HI "vnx2si")
-  (VNx1SI "vnx1di") (VNx2SI "vnx1di") (VNx4SI "vnx1di")
-  (VNx8SI "vnx1di") (VNx16SI "vnx1di")
-  (VNx1HF "vnx2sf") (VNx2HF "vnx2sf") (VNx4HF "vnx2sf") (VNx8HF "vnx2sf") (VNx16HF "vnx2sf") (VNx32HF "vnx2sf")
-  (VNx1SF "vnx1df") (VNx2SF "vnx1df")
-  (VNx4SF "vnx1df") (VNx8SF "vnx1df") (VNx16SF "vnx1df")
-])
-
-(define_mode_attr vwlmul1_zve32 [
-  (VNx1QI "vnx2hi") (VNx2QI "vnx2hi") (VNx4QI "vnx2hi")
-  (VNx8QI "vnx2hi") (VNx16QI "vnx2hi") (VNx32QI "vnx2hi")
-  (VNx1HI "vnx1si") (VNx2HI "vnx1si") (VNx4HI "vnx1si")
-  (VNx8HI "vnx1si") (VNx16HI "vnx1si")
-])
-
 (define_mode_attr VDEMOTE [
   (VNx1DI "VNx2SI") (VNx2DI "VNx4SI")
   (VNx4DI "VNx8SI") (VNx8DI "VNx16SI") (VNx16DI "VNx32SI")
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index efce992a012..884e7435cc2 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -7407,60 +7407,101 @@  (define_insn "@pred_reduc_<reduc><VDI:mode><VDI_LMUL1:mode>"
   ]
 )
 
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"           "=&vr,  &vr")
-	(unspec:<VWLMUL1>
-	  [(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")
+;; Integer Reduction Widen for QI, HI = QI op HI
+(define_insn "@pred_widen_reduc_plus<v_su><VQI:mode><VHI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VHI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VHI_LMUL1
+	[
+	  (unspec:<VQI:VM>
+	    [
+	      (match_operand:<VQI: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")
 	      (reg:SI VL_REGNUM)
-	      (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-	   (match_operand:VWI 3 "register_operand"             "   vr,   vr")
-	   (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-	   (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+	      (reg:SI VTYPE_REGNUM)
+	    ] UNSPEC_VPREDICATE
+	  )
+	  (match_operand:VQI          3 "register_operand"      "   vr,   vr")
+	  (match_operand:VHI_LMUL1    4 "register_operand"      "   vr,   vr")
+	  (match_operand:VHI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+	] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VQI:MODE>")
+  ]
+)
 
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"           "=&vr,  &vr")
-	(unspec:<VWLMUL1_ZVE64>
-	  [(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")
+;; Integer Reduction Widen for HI, SI = HI op SI
+(define_insn "@pred_widen_reduc_plus<v_su><VHI:mode><VSI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VSI_LMUL1
+	[
+	  (unspec:<VHI:VM>
+	    [
+	      (match_operand:<VHI: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")
 	      (reg:SI VL_REGNUM)
-	      (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-	   (match_operand:VWI_ZVE64 3 "register_operand"             "   vr,   vr")
-	   (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-	   (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+	      (reg:SI VTYPE_REGNUM)
+	    ] UNSPEC_VPREDICATE
+	  )
+	  (match_operand:VHI          3 "register_operand"      "   vr,   vr")
+	  (match_operand:VSI_LMUL1    4 "register_operand"      "   vr,   vr")
+	  (match_operand:VSI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+	] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
-
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VHI:MODE>")
+  ]
+)
 
-(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>"
-  [(set (match_operand:<VWLMUL1_ZVE32> 0 "register_operand"           "=&vr,  &vr")
-	(unspec:<VWLMUL1_ZVE32>
-	  [(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")
+;; Integer Reduction Widen for SI, DI = SI op DI
+(define_insn "@pred_widen_reduc_plus<v_su><VSI:mode><VDI_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDI_LMUL1        0 "register_operand"      "=&vr,&vr")
+      (unspec:VDI_LMUL1
+	[
+	  (unspec:<VSI:VM>
+	    [
+	      (match_operand:<VSI: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")
 	      (reg:SI VL_REGNUM)
-	      (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
-	   (match_operand:VWI_ZVE32 3 "register_operand"             "   vr,   vr")
-	   (match_operand:<VWLMUL1_ZVE32> 4 "register_operand"       "   vr,   vr")
-	   (match_operand:<VWLMUL1_ZVE32> 2 "vector_merge_operand"   "   vu,    0")] WREDUC))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+	      (reg:SI VTYPE_REGNUM)
+	    ] UNSPEC_VPREDICATE
+	  )
+	  (match_operand:VSI          3 "register_operand"      "   vr,   vr")
+	  (match_operand:VDI_LMUL1    4 "register_operand"      "   vr,   vr")
+	  (match_operand:VDI_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+	] WREDUC
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vwredsum<v_su>.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "viwred")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "viwred")
+    (set_attr "mode" "<VSI:MODE>")
+  ]
+)
 
 ;; Float Reduction for HF
 (define_insn "@pred_reduc_<reduc><VHF:mode><VHF_LMUL1:mode>"
@@ -7714,47 +7755,81 @@  (define_insn "@pred_reduc_plus<order><VDF:mode><VDF_LMUL1:mode>"
   ]
 )
 
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1>"
-  [(set (match_operand:<VWLMUL1> 0 "register_operand"             "=&vr,  &vr")
-	(unspec:<VWLMUL1>
-	  [(unspec:<VWLMUL1>
-	    [(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")
-	        (reg:SI VL_REGNUM)
-	        (reg:SI VTYPE_REGNUM)
-	        (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-	     (match_operand:VWF 3 "register_operand"             "   vr,   vr")
-	     (match_operand:<VWLMUL1> 4 "register_operand"       "   vr,   vr")
-	     (match_operand:<VWLMUL1> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN >= 128"
+;; Float Widen Reduction for HF, aka SF = HF op SF
+(define_insn "@pred_widen_reduc_plus<order><VHF:mode><VSF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VSF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VSF_LMUL1
+	[
+	  (unspec:VSF_LMUL1
+	    [
+	      (unspec:<VHF:VM>
+		[
+		  (match_operand:<VHF:VM> 1 "vector_merge_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")
+		  (reg:SI VL_REGNUM)
+		  (reg:SI VTYPE_REGNUM)
+		  (reg:SI FRM_REGNUM)
+		] UNSPEC_VPREDICATE
+	      )
+	      (match_operand:VHF          3 "register_operand"      "   vr,   vr")
+	      (match_operand:VSF_LMUL1    4 "register_operand"      "   vr,   vr")
+	      (match_operand:VSF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+	    ] UNSPEC_WREDUC_SUM
+	  )
+	] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VHF:MODE>")
+  ]
+)
 
-(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1_zve64>"
-  [(set (match_operand:<VWLMUL1_ZVE64> 0 "register_operand"             "=&vr,  &vr")
-	(unspec:<VWLMUL1_ZVE64>
-	  [(unspec:<VWLMUL1_ZVE64>
-	    [(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")
-	        (reg:SI VL_REGNUM)
-	        (reg:SI VTYPE_REGNUM)
-	        (reg:SI FRM_REGNUM)] UNSPEC_VPREDICATE)
-	     (match_operand:VWF_ZVE64 3 "register_operand"             "   vr,   vr")
-	     (match_operand:<VWLMUL1_ZVE64> 4 "register_operand"       "   vr,   vr")
-	     (match_operand:<VWLMUL1_ZVE64> 2 "vector_merge_operand"   "   vu,    0")] UNSPEC_WREDUC_SUM)] ORDER))]
-  "TARGET_VECTOR && TARGET_MIN_VLEN == 64"
+;; Float Widen Reduction for SF, aka DF = SF * DF
+(define_insn "@pred_widen_reduc_plus<order><VSF:mode><VDF_LMUL1:mode>"
+  [
+    (set
+      (match_operand:VDF_LMUL1            0 "register_operand"      "=&vr, &vr")
+      (unspec:VDF_LMUL1
+	[
+	  (unspec:VDF_LMUL1
+	    [
+	      (unspec:<VSF:VM>
+		[
+		  (match_operand:<VSF:VM> 1 "vector_merge_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")
+		  (reg:SI VL_REGNUM)
+		  (reg:SI VTYPE_REGNUM)
+		  (reg:SI FRM_REGNUM)
+		] UNSPEC_VPREDICATE
+	      )
+	      (match_operand:VSF          3 "register_operand"      "   vr,   vr")
+	      (match_operand:VDF_LMUL1    4 "register_operand"      "   vr,   vr")
+	      (match_operand:VDF_LMUL1    2 "vector_merge_operand"  "   vu,    0")
+	    ] UNSPEC_WREDUC_SUM
+	  )
+	] ORDER
+      )
+    )
+  ]
+  "TARGET_VECTOR"
   "vfwred<order>sum.vs\t%0,%3,%4%p1"
-  [(set_attr "type" "vfwred<order>")
-   (set_attr "mode" "<MODE>")])
+  [
+    (set_attr "type" "vfwred<order>")
+    (set_attr "mode" "<VSF:MODE>")
+  ]
+)
 
 ;; -------------------------------------------------------------------------------
 ;; ---- Predicated permutation operations
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
new file mode 100644
index 00000000000..d83eea925a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f_zvfh -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
new file mode 100644
index 00000000000..a8ea018ccc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-1.h
@@ -0,0 +1,9 @@ 
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16m8_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16m8_f32m1(vfloat16m8_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16m8_f32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
new file mode 100644
index 00000000000..cdcde1b89a4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.c
@@ -0,0 +1,8 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d_zvfh -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-1.h"
+#include "pr110299-2.h"
+
+/* { dg-final { scan-assembler-times {vfwredosum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
+/* { dg-final { scan-assembler-times {vfwredusum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
new file mode 100644
index 00000000000..51d4d4470d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-2.h
@@ -0,0 +1,17 @@ 
+#include "riscv_vector.h"
+
+vfloat32m1_t test_vfwredosum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat32m1_t test_vfwredusum_vs_f16mf4_f32m1(vfloat16mf4_t vector, vfloat32m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f16mf4_f32m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredusum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredusum_vs_f32m8_f64m1(vector, scalar, vl);
+}
+
+vfloat64m1_t test_vfwredosum_vs_f32m8_f64m1(vfloat32m8_t vector, vfloat64m1_t scalar, size_t vl) {
+  return __riscv_vfwredosum_vs_f32m8_f64m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
new file mode 100644
index 00000000000..0f84c17d6f1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.c
@@ -0,0 +1,7 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve32f -mabi=ilp32f -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
new file mode 100644
index 00000000000..3416196b8cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-3.h
@@ -0,0 +1,17 @@ 
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf4_i16m1(vint8mf4_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf4_i16m1(vector, scalar, vl);
+}
+
+vint32m1_t test_vwredsum_vs_i16m8_i32m1(vint16m8_t vector, vint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i16m8_i32m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf4_u16m1(vuint8mf4_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf4_u16m1(vector, scalar, vl);
+}
+
+vuint32m1_t test_vwredsumu_vs_u16m8_u32m1(vuint16m8_t vector, vuint32m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u16m8_u32m1(vector, scalar, vl);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
new file mode 100644
index 00000000000..8297cd62f65
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.c
@@ -0,0 +1,8 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_zve64d -mabi=ilp32d -O3 -Wno-psabi" } */
+
+#include "pr110299-3.h"
+#include "pr110299-4.h"
+
+/* { dg-final { scan-assembler-times {vwredsum\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
+/* { dg-final { scan-assembler-times {vwredsumu\.vs\s+v[0-9]+,\s*v[0-9]+,\s*v[0-9]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
new file mode 100644
index 00000000000..b4f7d403fe3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110299-4.h
@@ -0,0 +1,17 @@ 
+#include "riscv_vector.h"
+
+vint16m1_t test_vwredsum_vs_i8mf8_i16m1(vint8mf8_t vector, vint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i8mf8_i16m1(vector, scalar, vl);
+}
+
+vint64m1_t test_vwredsum_vs_i32m8_i64m1(vint32m8_t vector, vint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsum_vs_i32m8_i64m1(vector, scalar, vl);
+}
+
+vuint16m1_t test_vwredsumu_vs_u8mf8_u16m1(vuint8mf8_t vector, vuint16m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u8mf8_u16m1(vector, scalar, vl);
+}
+
+vuint64m1_t test_vwredsumu_vs_u32m8_u64m1(vuint32m8_t vector, vuint64m1_t scalar, size_t vl) {
+  return __riscv_vwredsumu_vs_u32m8_u64m1(vector, scalar, vl);
+}