diff mbox series

RISC-V: Add vsext/vzext C/C++ intrinsic support

Message ID 20230206050656.211738-1-juzhe.zhong@rivai.ai
State New
Headers show
Series RISC-V: Add vsext/vzext C/C++ intrinsic support | expand

Commit Message

juzhe.zhong@rivai.ai Feb. 6, 2023, 5:06 a.m. UTC
From: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>

gcc/ChangeLog:

        * config/riscv/iterators.md: Add sign_extend/zero_extend.
        * config/riscv/riscv-vector-builtins-bases.cc (class ext): New class.
        (BASE): Ditto.
        * config/riscv/riscv-vector-builtins-bases.h: Add vsext/vzext support.
        * config/riscv/riscv-vector-builtins-functions.def (vsext): New macro define.
        (vzext): Ditto.
        * config/riscv/riscv-vector-builtins-shapes.cc (struct alu_def): Adjust for vsext/vzext support.
        * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_WEXTI_OPS): New macro define.
        (DEF_RVV_QEXTI_OPS): Ditto.
        (DEF_RVV_OEXTI_OPS): Ditto.
        (DEF_RVV_WEXTU_OPS): Ditto.
        (DEF_RVV_QEXTU_OPS): Ditto.
        (DEF_RVV_OEXTU_OPS): Ditto.
        (vint16mf4_t): Ditto.
        (vint16mf2_t): Ditto.
        (vint16m1_t): Ditto.
        (vint16m2_t): Ditto.
        (vint16m4_t): Ditto.
        (vint16m8_t): Ditto.
        (vint32mf2_t): Ditto.
        (vint32m1_t): Ditto.
        (vint32m2_t): Ditto.
        (vint32m4_t): Ditto.
        (vint32m8_t): Ditto.
        (vint64m1_t): Ditto.
        (vint64m2_t): Ditto.
        (vint64m4_t): Ditto.
        (vint64m8_t): Ditto.
        (vuint16mf4_t): Ditto.
        (vuint16mf2_t): Ditto.
        (vuint16m1_t): Ditto.
        (vuint16m2_t): Ditto.
        (vuint16m4_t): Ditto.
        (vuint16m8_t): Ditto.
        (vuint32mf2_t): Ditto.
        (vuint32m1_t): Ditto.
        (vuint32m2_t): Ditto.
        (vuint32m4_t): Ditto.
        (vuint32m8_t): Ditto.
        (vuint64m1_t): Ditto.
        (vuint64m2_t): Ditto.
        (vuint64m4_t): Ditto.
        (vuint64m8_t): Ditto.
        * config/riscv/riscv-vector-builtins.cc (DEF_RVV_WEXTI_OPS): Ditto.
        (DEF_RVV_QEXTI_OPS): Ditto.
        (DEF_RVV_OEXTI_OPS): Ditto.
        (DEF_RVV_WEXTU_OPS): Ditto.
        (DEF_RVV_QEXTU_OPS): Ditto.
        (DEF_RVV_OEXTU_OPS): Ditto.
        (rvv_arg_type_info::get_base_vector_type): Add sign_exted/zero_extend support.
        (rvv_arg_type_info::get_tree_type): Ditto.
        * config/riscv/riscv-vector-builtins.h (enum rvv_base_type): Ditto.
        * config/riscv/vector-iterators.md (z): New attribute.
        * config/riscv/vector.md (@pred_<optab><mode>_vf2): New pattern.
        (@pred_<optab><mode>_vf4): Ditto.
        (@pred_<optab><mode>_vf8): Ditto.

---
 gcc/config/riscv/iterators.md                 |   4 +-
 .../riscv/riscv-vector-builtins-bases.cc      |  25 ++++
 .../riscv/riscv-vector-builtins-bases.h       |   2 +
 .../riscv/riscv-vector-builtins-functions.def |   6 +
 .../riscv/riscv-vector-builtins-shapes.cc     |  21 ++-
 .../riscv/riscv-vector-builtins-types.def     | 104 ++++++++++++++
 gcc/config/riscv/riscv-vector-builtins.cc     | 131 +++++++++++++++++-
 gcc/config/riscv/riscv-vector-builtins.h      |   3 +
 gcc/config/riscv/vector-iterators.md          |  39 ++++++
 gcc/config/riscv/vector.md                    |  80 ++++++++++-
 10 files changed, 401 insertions(+), 14 deletions(-)
diff mbox series

Patch

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 7e5415cc80b..f95dd405e12 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -207,7 +207,9 @@ 
 			 (ss_plus "ssadd")
 			 (us_plus "usadd")
 			 (ss_minus "sssub")
-			 (us_minus "ussub")])
+			 (us_minus "ussub")
+			 (sign_extend "extend")
+			 (zero_extend "zero_extend")])
 
 ;; <or_optab> code attributes
 (define_code_attr or_optab [(ior "ior")
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 7e6ee1d7b53..1a9469a370a 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -197,6 +197,27 @@  public:
   }
 };
 
+/* Implements vsext.vf2/vsext.vf4/vsext.vf8/vzext.vf2/vzext.vf4/vzext.vf8.  */
+template<rtx_code CODE>
+class ext : public function_base
+{
+public:
+  rtx expand (function_expander &e) const override
+  {
+    switch (e.op_info->op)
+      {
+      case OP_TYPE_vf2:
+	return e.use_exact_insn (code_for_pred_vf2 (CODE, e.vector_mode ()));
+      case OP_TYPE_vf4:
+	return e.use_exact_insn (code_for_pred_vf4 (CODE, e.vector_mode ()));
+      case OP_TYPE_vf8:
+	return e.use_exact_insn (code_for_pred_vf8 (CODE, e.vector_mode ()));
+      default:
+	gcc_unreachable ();
+      }
+  }
+};
+
 static CONSTEXPR const vsetvl<false> vsetvl_obj;
 static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
 static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
@@ -241,6 +262,8 @@  static CONSTEXPR const binop<UDIV> vdivu_obj;
 static CONSTEXPR const binop<UMOD> vremu_obj;
 static CONSTEXPR const unop<NEG> vneg_obj;
 static CONSTEXPR const unop<NOT> vnot_obj;
+static CONSTEXPR const ext<SIGN_EXTEND> vsext_obj;
+static CONSTEXPR const ext<ZERO_EXTEND> vzext_obj;
 static CONSTEXPR const binop<SS_PLUS> vsadd_obj;
 static CONSTEXPR const binop<SS_MINUS> vssub_obj;
 static CONSTEXPR const binop<US_PLUS> vsaddu_obj;
@@ -295,6 +318,8 @@  BASE (vdivu)
 BASE (vremu)
 BASE (vneg)
 BASE (vnot)
+BASE (vsext)
+BASE (vzext)
 BASE (vsadd)
 BASE (vssub)
 BASE (vsaddu)
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h
index a59fd918af8..71629f36738 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -68,6 +68,8 @@  extern const function_base *const vdivu;
 extern const function_base *const vremu;
 extern const function_base *const vneg;
 extern const function_base *const vnot;
+extern const function_base *const vsext;
+extern const function_base *const vzext;
 extern const function_base *const vsadd;
 extern const function_base *const vssub;
 extern const function_base *const vsaddu;
diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def b/gcc/config/riscv/riscv-vector-builtins-functions.def
index 74a1864b725..42514ed5a37 100644
--- a/gcc/config/riscv/riscv-vector-builtins-functions.def
+++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
@@ -100,6 +100,12 @@  DEF_RVV_FUNCTION (vdivu, alu, full_preds, u_vvx_ops)
 DEF_RVV_FUNCTION (vremu, alu, full_preds, u_vvx_ops)
 DEF_RVV_FUNCTION (vneg, alu, full_preds, iu_v_ops)
 DEF_RVV_FUNCTION (vnot, alu, full_preds, iu_v_ops)
+DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf2_ops)
+DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf4_ops)
+DEF_RVV_FUNCTION (vsext, alu, full_preds, i_vf8_ops)
+DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf2_ops)
+DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf4_ops)
+DEF_RVV_FUNCTION (vzext, alu, full_preds, u_vf8_ops)
 /* 12. Vector Fixed-Point Arithmetic Instructions. */
 DEF_RVV_FUNCTION (vsadd, alu, full_preds, i_vvv_ops)
 DEF_RVV_FUNCTION (vssub, alu, full_preds, i_vvv_ops)
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index d6dc4c7049e..e772a7ca475 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -192,14 +192,23 @@  struct alu_def : public build_base
 		  bool overloaded_p) const override
   {
     b.append_base_name (instance.base_name);
-    /* vop<sew>_v --> vop<sew>_v_<type>.  */
-    if (!overloaded_p)
+
+    /* vop<sew> --> vop<sew>_<op>. According to rvv-intrinsic-doc, _vv/_vx/_v
+       API doesn't have OP suffix in overloaded function name, otherwise, we
+       always append OP suffix in function name. For example, vsext_vf2.  */
+    if (instance.op_info->op == OP_TYPE_vv || instance.op_info->op == OP_TYPE_vx
+	|| instance.op_info->op == OP_TYPE_v)
       {
-	/* vop<sew> --> vop<sew>_v.  */
-	b.append_name (operand_suffixes[instance.op_info->op]);
-	/* vop<sew>_v --> vop<sew>_v_<type>.  */
-	b.append_name (type_suffixes[instance.type.index].vector);
+	if (!overloaded_p)
+	  b.append_name (operand_suffixes[instance.op_info->op]);
       }
+    else
+      b.append_name (operand_suffixes[instance.op_info->op]);
+
+    /* vop<sew>_<op> --> vop<sew>_<op>_<type>.  */
+    if (!overloaded_p)
+      b.append_name (type_suffixes[instance.type.index].vector);
+
     /* According to rvv-intrinsic-doc, it does not add "_m" suffix
        for vop_m C++ overloaded API.  */
     if (overloaded_p && instance.pred == PRED_TYPE_m)
diff --git a/gcc/config/riscv/riscv-vector-builtins-types.def b/gcc/config/riscv/riscv-vector-builtins-types.def
index a95fad031be..d3129b9f753 100644
--- a/gcc/config/riscv/riscv-vector-builtins-types.def
+++ b/gcc/config/riscv/riscv-vector-builtins-types.def
@@ -42,6 +42,42 @@  along with GCC; see the file COPYING3. If not see
 #define DEF_RVV_B_OPS(TYPE, REQUIRE)
 #endif
 
+/* Use "DEF_RVV_WEXTI_OPS" macro include Double-Widening signed integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_WEXTI_OPS
+#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_QEXTI_OPS" macro include Quad-Widening signed integer which will
+   be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_QEXTI_OPS
+#define DEF_RVV_QEXTI_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_OEXTI_OPS" macro include Oct-Widening signed integer which will
+   be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_OEXTI_OPS
+#define DEF_RVV_OEXTI_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_WEXTU_OPS" macro include Double-Widening unsigned integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_WEXTU_OPS
+#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_QEXTU_OPS" macro include Quad-Widening unsigned integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_QEXTU_OPS
+#define DEF_RVV_QEXTU_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_OEXTU_OPS" macro include Oct-Widening unsigned integer which
+   will be iterated and registered as intrinsic functions.  */
+#ifndef DEF_RVV_OEXTU_OPS
+#define DEF_RVV_OEXTU_OPS(TYPE, REQUIRE)
+#endif
+
 DEF_RVV_I_OPS (vint8mf8_t, RVV_REQUIRE_ZVE64)
 DEF_RVV_I_OPS (vint8mf4_t, 0)
 DEF_RVV_I_OPS (vint8mf2_t, 0)
@@ -106,7 +142,75 @@  DEF_RVV_B_OPS (vbool4_t, 0)
 DEF_RVV_B_OPS (vbool2_t, 0)
 DEF_RVV_B_OPS (vbool1_t, 0)
 
+DEF_RVV_WEXTI_OPS (vint16mf4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint16mf2_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m1_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m2_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m4_t, 0)
+DEF_RVV_WEXTI_OPS (vint16m8_t, 0)
+DEF_RVV_WEXTI_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint32m1_t, 0)
+DEF_RVV_WEXTI_OPS (vint32m2_t, 0)
+DEF_RVV_WEXTI_OPS (vint32m4_t, 0)
+DEF_RVV_WEXTI_OPS (vint32m8_t, 0)
+DEF_RVV_WEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_QEXTI_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint32m1_t, 0)
+DEF_RVV_QEXTI_OPS (vint32m2_t, 0)
+DEF_RVV_QEXTI_OPS (vint32m4_t, 0)
+DEF_RVV_QEXTI_OPS (vint32m8_t, 0)
+DEF_RVV_QEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_OEXTI_OPS (vint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTI_OPS (vint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTI_OPS (vint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTI_OPS (vint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_WEXTU_OPS (vuint16mf4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint16mf2_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m1_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m2_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m4_t, 0)
+DEF_RVV_WEXTU_OPS (vuint16m8_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint32m1_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32m2_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32m4_t, 0)
+DEF_RVV_WEXTU_OPS (vuint32m8_t, 0)
+DEF_RVV_WEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_QEXTU_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint32m1_t, 0)
+DEF_RVV_QEXTU_OPS (vuint32m2_t, 0)
+DEF_RVV_QEXTU_OPS (vuint32m4_t, 0)
+DEF_RVV_QEXTU_OPS (vuint32m8_t, 0)
+DEF_RVV_QEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_QEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64)
+
+DEF_RVV_OEXTU_OPS (vuint64m1_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTU_OPS (vuint64m2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTU_OPS (vuint64m4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_OEXTU_OPS (vuint64m8_t, RVV_REQUIRE_ZVE64)
+
 #undef DEF_RVV_I_OPS
 #undef DEF_RVV_U_OPS
 #undef DEF_RVV_F_OPS
 #undef DEF_RVV_B_OPS
+#undef DEF_RVV_WEXTI_OPS
+#undef DEF_RVV_QEXTI_OPS
+#undef DEF_RVV_OEXTI_OPS
+#undef DEF_RVV_WEXTU_OPS
+#undef DEF_RVV_QEXTU_OPS
+#undef DEF_RVV_OEXTU_OPS
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 95a949aab7c..85adcf328ce 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -160,6 +160,48 @@  static const rvv_type_info b_ops[] = {
 #include "riscv-vector-builtins-types.def"
   {NUM_VECTOR_TYPES, 0}};
 
+/* A list of Double-Widening signed integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info wexti_ops[] = {
+#define DEF_RVV_WEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Quad-Widening signed integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info qexti_ops[] = {
+#define DEF_RVV_QEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Oct-Widening signed integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info oexti_ops[] = {
+#define DEF_RVV_OEXTI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Double-Widening unsigned integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info wextu_ops[] = {
+#define DEF_RVV_WEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Quad-Widening unsigned integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info qextu_ops[] = {
+#define DEF_RVV_QEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
+/* A list of Oct-Widening unsigned integer will be registered for intrinsic
+ * functions.  */
+static const rvv_type_info oextu_ops[] = {
+#define DEF_RVV_OEXTU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+  {NUM_VECTOR_TYPES, 0}};
+
 static CONSTEXPR const rvv_arg_type_info rvv_arg_type_info_end
   = rvv_arg_type_info (NUM_BASE_TYPES);
 
@@ -269,6 +311,18 @@  static CONSTEXPR const rvv_arg_type_info vector_size_args[]
   = {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info (RVV_BASE_size),
      rvv_arg_type_info_end};
 
+/* A list of args for vector_type func (double demote type) function.  */
+static CONSTEXPR const rvv_arg_type_info vf2_args[]
+  = {rvv_arg_type_info (RVV_BASE_double_trunc_vector), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (quad demote type) function.  */
+static CONSTEXPR const rvv_arg_type_info vf4_args[]
+  = {rvv_arg_type_info (RVV_BASE_quad_trunc_vector), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (oct demote type) function.  */
+static CONSTEXPR const rvv_arg_type_info vf8_args[]
+  = {rvv_arg_type_info (RVV_BASE_oct_trunc_vector), rvv_arg_type_info_end};
+
 /* A list of none preds that will be registered for intrinsic functions.  */
 static CONSTEXPR const predication_type_index none_preds[]
   = {PRED_TYPE_none, NUM_PRED_TYPES};
@@ -481,6 +535,54 @@  static CONSTEXPR const rvv_op_info iu_v_ops
      rvv_arg_type_info (RVV_BASE_vector), /* Return type */
      v_args /* Args */};
 
+/* A static operand information for vector_type func (double demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_vf2_ops
+  = {wexti_ops,				  /* Types */
+     OP_TYPE_vf2,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf2_args /* Args */};
+
+/* A static operand information for vector_type func (quad demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_vf4_ops
+  = {qexti_ops,				  /* Types */
+     OP_TYPE_vf4,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf4_args /* Args */};
+
+/* A static operand information for vector_type func (oct demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info i_vf8_ops
+  = {oexti_ops,				  /* Types */
+     OP_TYPE_vf8,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf8_args /* Args */};
+
+/* A static operand information for vector_type func (double demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vf2_ops
+  = {wextu_ops,				  /* Types */
+     OP_TYPE_vf2,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf2_args /* Args */};
+
+/* A static operand information for vector_type func (quad demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vf4_ops
+  = {qextu_ops,				  /* Types */
+     OP_TYPE_vf4,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf4_args /* Args */};
+
+/* A static operand information for vector_type func (oct demote type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info u_vf8_ops
+  = {oextu_ops,				  /* Types */
+     OP_TYPE_vf8,			  /* Suffix */
+     rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+     vf8_args /* Args */};
+
 /* A list of all RVV intrinsic functions.  */
 static function_group_info function_groups[] = {
 #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)                         \
@@ -763,7 +865,7 @@  rvv_arg_type_info::get_base_vector_type (tree type) const
   if (!type)
     return NUM_VECTOR_TYPES;
   poly_int64 nunits = GET_MODE_NUNITS (TYPE_MODE (type));
-  machine_mode inner_mode;
+  machine_mode inner_mode = GET_MODE_INNER (TYPE_MODE (type));
   bool unsigned_p = TYPE_UNSIGNED (type);
   switch (base_type)
     {
@@ -787,6 +889,30 @@  rvv_arg_type_info::get_base_vector_type (tree type) const
       inner_mode = GET_MODE_INNER (TYPE_MODE (type));
       unsigned_p = true;
       break;
+    case RVV_BASE_double_trunc_vector:
+      if (inner_mode == DImode)
+        inner_mode = SImode;
+      else if (inner_mode == SImode)
+        inner_mode = HImode;
+      else if (inner_mode == HImode)
+        inner_mode = QImode;
+      else
+        gcc_unreachable ();
+      break;
+    case RVV_BASE_quad_trunc_vector:
+      if (inner_mode == DImode)
+        inner_mode = HImode;
+      else if (inner_mode == SImode)
+        inner_mode = QImode;
+      else
+        gcc_unreachable ();
+      break;
+    case RVV_BASE_oct_trunc_vector:
+      if (inner_mode == DImode)
+        inner_mode = QImode;
+      else
+        gcc_unreachable ();
+      break;
     default:
       return NUM_VECTOR_TYPES;
     }
@@ -851,6 +977,9 @@  rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const
     case RVV_BASE_uint32_index:
     case RVV_BASE_uint64_index:
     case RVV_BASE_shift_vector:
+    case RVV_BASE_double_trunc_vector:
+    case RVV_BASE_quad_trunc_vector:
+    case RVV_BASE_oct_trunc_vector:
       if (get_base_vector_type (builtin_types[type_idx].vector)
 	  != NUM_VECTOR_TYPES)
 	return builtin_types[get_base_vector_type (
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index c20d8f8835c..f14b6a55ec2 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -152,6 +152,9 @@  enum rvv_base_type
   RVV_BASE_uint32_index,
   RVV_BASE_uint64_index,
   RVV_BASE_shift_vector,
+  RVV_BASE_double_trunc_vector,
+  RVV_BASE_quad_trunc_vector,
+  RVV_BASE_oct_trunc_vector,
   NUM_BASE_TYPES
 };
 
diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md
index 2460ed670c0..6528e5711a4 100644
--- a/gcc/config/riscv/vector-iterators.md
+++ b/gcc/config/riscv/vector-iterators.md
@@ -164,6 +164,24 @@ 
   (VNx64BI "TARGET_MIN_VLEN > 32")
 ])
 
+(define_mode_iterator VWEXTI [
+  VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32")
+  VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
+  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
+  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
+])
+
+(define_mode_iterator VQEXTI [
+  VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
+  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
+  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
+])
+
+(define_mode_iterator VOEXTI [
+  (VNx1DI "TARGET_MIN_VLEN > 32") (VNx2DI "TARGET_MIN_VLEN > 32")
+  (VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
+])
+
 (define_mode_attr VM [
   (VNx1QI "VNx1BI") (VNx2QI "VNx2BI") (VNx4QI "VNx4BI") (VNx8QI "VNx8BI") (VNx16QI "VNx16BI") (VNx32QI "VNx32BI") (VNx64QI "VNx64BI")
   (VNx1HI "VNx1BI") (VNx2HI "VNx2BI") (VNx4HI "VNx4BI") (VNx8HI "VNx8BI") (VNx16HI "VNx16BI") (VNx32HI "VNx32BI")
@@ -199,6 +217,25 @@ 
   (VNx1DF "64") (VNx2DF "64") (VNx4DF "64") (VNx8DF "64")
 ])
 
+(define_mode_attr V_DOUBLE_TRUNC [
+  (VNx1HI "VNx1QI") (VNx2HI "VNx2QI")  (VNx4HI "VNx4QI")  (VNx8HI "VNx8QI")  
+  (VNx16HI "VNx16QI") (VNx32HI "VNx32QI")
+  (VNx1SI "VNx1HI") (VNx2SI "VNx2HI") (VNx4SI "VNx4HI") (VNx8SI "VNx8HI") 
+  (VNx16SI "VNx16HI")
+  (VNx1DI "VNx1SI") (VNx2DI "VNx2SI") (VNx4DI "VNx4SI") (VNx8DI "VNx8SI")
+])
+
+(define_mode_attr V_QUAD_TRUNC [
+  (VNx1SI "VNx1QI") (VNx2SI "VNx2QI") (VNx4SI "VNx4QI") (VNx8SI "VNx8QI") 
+  (VNx16SI "VNx16QI")
+  (VNx1DI "VNx1HI") (VNx2DI "VNx2HI")
+  (VNx4DI "VNx4HI") (VNx8DI "VNx8HI")
+])
+
+(define_mode_attr V_OCT_TRUNC [
+  (VNx1DI "VNx1QI") (VNx2DI "VNx2QI") (VNx4DI "VNx4QI") (VNx8DI "VNx8QI")
+])
+
 (define_int_iterator ORDER [UNSPEC_ORDERED UNSPEC_UNORDERED])
 
 (define_int_attr order [
@@ -415,3 +452,5 @@ 
 			      (umin "%3,%4")
 			      (umax "%3,%4")
 			      (mult "%3,%4")])
+
+(define_code_attr sz [(sign_extend "s") (zero_extend "z")])
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index 44584e17105..8bafbdc8704 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -142,7 +142,7 @@ 
 ;; It is valid for instruction that require sew/lmul ratio.
 (define_attr "ratio" ""
   (cond [(eq_attr "type" "vimov,vfmov,vldux,vldox,vstux,vstox,\
-			  vialu,vshift,vicmp,vimul,vidiv,vsalu")
+			  vialu,vshift,vicmp,vimul,vidiv,vsalu,vext")
 	   (const_int INVALID_ATTRIBUTE)
 	 (eq_attr "mode" "VNx1QI,VNx1BI")
 	   (symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
@@ -193,13 +193,14 @@ 
 ;; The index of operand[] to get the merge op.
 (define_attr "merge_op_idx" ""
 	(cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu,vldux,vldox,\
-				vialu,vshift,vicmp,vimul,vidiv,vsalu")
+				vialu,vshift,vicmp,vimul,vidiv,vsalu,vext")
 	 (const_int 2)]
 	(const_int INVALID_ATTRIBUTE)))
 
 ;; The index of operand[] to get the avl op.
 (define_attr "vl_op_idx" ""
-  (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,vstox")
+  (cond [(eq_attr "type" "vlde,vste,vimov,vfmov,vldm,vstm,vmalu,vsts,vstux,\
+			  vstox,vext")
 	   (const_int 4)
 
 	 ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
@@ -215,7 +216,7 @@ 
 
 ;; The tail policy op value.
 (define_attr "ta" ""
-  (cond [(eq_attr "type" "vlde,vimov,vfmov")
+  (cond [(eq_attr "type" "vlde,vimov,vfmov,vext")
 	   (symbol_ref "riscv_vector::get_ta(operands[5])")
 
 	 ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
@@ -231,7 +232,7 @@ 
 
 ;; The mask policy op value.
 (define_attr "ma" ""
-  (cond [(eq_attr "type" "vlde")
+  (cond [(eq_attr "type" "vlde,vext")
 	   (symbol_ref "riscv_vector::get_ma(operands[6])")
 
 	 ;; If operands[3] of "vlds" is not vector mode, it is pred_broadcast.
@@ -247,7 +248,7 @@ 
 
 ;; The avl type value.
 (define_attr "avl_type" ""
-  (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov")
+  (cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext")
 	   (symbol_ref "INTVAL (operands[7])")
 	 (eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
 	   (symbol_ref "INTVAL (operands[5])")
@@ -1803,3 +1804,70 @@ 
    (set (attr "ta") (symbol_ref "riscv_vector::get_ta(operands[5])"))
    (set (attr "ma") (symbol_ref "riscv_vector::get_ta(operands[6])"))
    (set (attr "avl_type") (symbol_ref "INTVAL (operands[7])"))])
+
+;; -------------------------------------------------------------------------------
+;; ---- Predicated integer widening operations
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - 11.3 Vector Integer Extension
+;; -------------------------------------------------------------------------------
+
+;; Vector Double-Widening Sign-extend and Zero-extend.
+(define_insn "@pred_<optab><mode>_vf2"
+  [(set (match_operand:VWEXTI 0 "register_operand"            "=&vr")
+	(if_then_else:VWEXTI
+	  (unspec:<VM>
+	    [(match_operand:<VM> 1 "vector_mask_operand"         "vmWc1")
+	     (match_operand 4 "vector_length_operand"            "   rK")
+	     (match_operand 5 "const_int_operand"                "    i")
+	     (match_operand 6 "const_int_operand"                "    i")
+	     (match_operand 7 "const_int_operand"                "    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+	  (any_extend:VWEXTI
+	    (match_operand:<V_DOUBLE_TRUNC> 3 "register_operand" "   vr"))
+	  (match_operand:VWEXTI 2 "vector_merge_operand"         "  0vu")))]
+  "TARGET_VECTOR"
+  "v<sz>ext.vf2\t%0,%3%p1"
+  [(set_attr "type" "vext")
+   (set_attr "mode" "<MODE>")])
+
+;; Vector Quad-Widening Sign-extend and Zero-extend.
+(define_insn "@pred_<optab><mode>_vf4"
+  [(set (match_operand:VQEXTI 0 "register_operand"          "=&vr")
+	(if_then_else:VQEXTI
+	  (unspec:<VM>
+	    [(match_operand:<VM> 1 "vector_mask_operand"       "vmWc1")
+	     (match_operand 4 "vector_length_operand"          "   rK")
+	     (match_operand 5 "const_int_operand"              "    i")
+	     (match_operand 6 "const_int_operand"              "    i")
+	     (match_operand 7 "const_int_operand"              "    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+	  (any_extend:VQEXTI
+	    (match_operand:<V_QUAD_TRUNC> 3 "register_operand" "   vr"))
+	  (match_operand:VQEXTI 2 "vector_merge_operand"       "  0vu")))]
+  "TARGET_VECTOR"
+  "v<sz>ext.vf4\t%0,%3%p1"
+  [(set_attr "type" "vext")
+   (set_attr "mode" "<MODE>")])
+
+;; Vector Oct-Widening Sign-extend and Zero-extend.
+(define_insn "@pred_<optab><mode>_vf8"
+  [(set (match_operand:VOEXTI 0 "register_operand"         "=&vr")
+	(if_then_else:VOEXTI
+	  (unspec:<VM>
+	    [(match_operand:<VM> 1 "vector_mask_operand"      "vmWc1")
+	     (match_operand 4 "vector_length_operand"         "   rK")
+	     (match_operand 5 "const_int_operand"             "    i")
+	     (match_operand 6 "const_int_operand"             "    i")
+	     (match_operand 7 "const_int_operand"             "    i")
+	     (reg:SI VL_REGNUM)
+	     (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+	  (any_extend:VOEXTI
+	    (match_operand:<V_OCT_TRUNC> 3 "register_operand" "   vr"))
+	  (match_operand:VOEXTI 2 "vector_merge_operand"      "  0vu")))]
+  "TARGET_VECTOR"
+  "v<sz>ext.vf8\t%0,%3%p1"
+  [(set_attr "type" "vext")
+   (set_attr "mode" "<MODE>")])