From: Yunze Zhu <[email protected]>
This commit add support for xtheadvector-specific indexed segment load/store
intrinsics with b/h/w suffix. We also defined enum to be used in
thead-vector-builtins-bases.cc
https://github.com/XUANTIE-RV/thead-extension-spec/pull/66
gcc/ChangeLog:
* config/riscv/riscv-vector-builtins-shapes.cc (struct
th_seg_loadstore_def):Define new builtin shapes.
* config/riscv/riscv-vector-builtins.cc:Define new operand informations.
* config/riscv/thead-vector-builtins-bases.cc (class th_vlxseg):New
function.
(class th_vsxseg):Ditto.
(BASE):New base_name.
* config/riscv/thead-vector-builtins-bases.h:New function_base.
* config/riscv/thead-vector-builtins-functions.def (th_vlxseg):New
intrinsics def.
(th_vlxsegu):Ditto.
(th_vsxseg):Ditto.
* config/riscv/thead-vector.md
(@pred_th_indexed_load<vlmem_op_attr><VT:mode><VI:mode>):New RTL mode.
(@pred_th_indexed_store<vlmem_op_attr><VT:mode><VI:mode>):Ditto.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/xtheadvector/vlxseg-vsxseg.c: New test.
* gcc.target/riscv/rvv/xtheadvector/vlxsegu-vsxseg.c: New test.
---
.../riscv/riscv-vector-builtins-shapes.cc | 4 +
gcc/config/riscv/riscv-vector-builtins.cc | 24 ++++
.../riscv/thead-vector-builtins-bases.cc | 78 +++++++++++
.../riscv/thead-vector-builtins-bases.h | 3 +
.../riscv/thead-vector-builtins-functions.def | 3 +
gcc/config/riscv/thead-vector.md | 60 +++++++++
.../riscv/rvv/xtheadvector/vlxseg-vsxseg.c | 125 ++++++++++++++++++
.../riscv/rvv/xtheadvector/vlxsegu-vsxseg.c | 125 ++++++++++++++++++
8 files changed, 422 insertions(+)
create mode 100644
gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxseg-vsxseg.c
create mode 100644
gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxsegu-vsxseg.c
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index b34eb4b2ee5..dab5e1a4e23 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -1402,10 +1402,14 @@ struct th_seg_loadstore_def : public build_base {
b.append_name ("__riscv_th_vlseg");
else if (strstr (instance.base_name, "vlsseg"))
b.append_name ("__riscv_th_vlsseg");
+ else if (strstr (instance.base_name, "vlxseg"))
+ b.append_name ("__riscv_th_vlxseg");
else if (strstr (instance.base_name, "vsseg"))
b.append_name ("__riscv_th_vsseg");
else if (strstr (instance.base_name, "vssseg"))
b.append_name ("__riscv_th_vssseg");
+ else if (strstr (instance.base_name, "vsxseg"))
+ b.append_name ("__riscv_th_vsxseg");
else
gcc_unreachable ();
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc
b/gcc/config/riscv/riscv-vector-builtins.cc
index adfbe6882fa..d7d44ea0a41 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -3411,6 +3411,30 @@ static CONSTEXPR const rvv_op_info
th_tuple_v_int_scalar_ptr_ptrdiff_ops
rvv_arg_type_info (RVV_BASE_void), /* Return type */
scalar_ptr_ptrdiff_args /* Args */};
+/* A static operand information for vector_type func (const scalar_type *,
+ * index_type) function registration. */
+static CONSTEXPR const rvv_op_info th_tuple_v_sint_scalar_const_ptr_index_ops
+ = {th_tuple_sint_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ scalar_const_ptr_index_args /* Args */};
+
+/* A static operand information for vector_type func (const scalar_type *,
+ * index_type) function registration. */
+static CONSTEXPR const rvv_op_info th_tuple_v_uint_scalar_const_ptr_index_ops
+ = {th_tuple_uint_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ scalar_const_ptr_index_args /* Args */};
+
+/* A static operand information for void func (scalar_type *, index_type,
+ * vector_type) function registration. */
+static CONSTEXPR const rvv_op_info th_tuple_v_int_scalar_ptr_index_ops
+ = {th_tuple_int_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_void), /* Return type */
+ scalar_ptr_index_args /* Args */};
+
/* A list of all RVV base function types. */
static CONSTEXPR const function_type_info function_types[] = {
#define DEF_RVV_TYPE_INDEX(
\
diff --git a/gcc/config/riscv/thead-vector-builtins-bases.cc
b/gcc/config/riscv/thead-vector-builtins-bases.cc
index 2c59b384d6c..5331e8138c1 100644
--- a/gcc/config/riscv/thead-vector-builtins-bases.cc
+++ b/gcc/config/riscv/thead-vector-builtins-bases.cc
@@ -193,6 +193,78 @@ public:
}
};
+/* Implements th.vlxseg (b/h/w)[u].v codegen. */
+template <bool IS_SIGNED = false>
+class th_vlxseg : public function_base {
+public:
+ unsigned int call_properties (const function_instance &) const override {
+ return CP_READ_MEMORY;
+ }
+
+ bool can_be_overloaded_p (enum predication_type_index pred) const override {
+ return pred != PRED_TYPE_none;
+ }
+
+ rtx expand (function_expander &e) const override {
+ gcc_assert (TARGET_XTHEADVECTOR);
+ unsigned sew = GET_MODE_BITSIZE (GET_MODE_INNER (e.vector_mode ()));
+ int UNSPEC;
+ switch (sew)
+ {
+ case 8:
+ UNSPEC = IS_SIGNED ? UNSPEC_TH_VLXSEGB : UNSPEC_TH_VLXSEGBU;
+ break;
+ case 16:
+ UNSPEC = IS_SIGNED ? UNSPEC_TH_VLXSEGH : UNSPEC_TH_VLXSEGHU;
+ break;
+ case 32:
+ UNSPEC = IS_SIGNED ? UNSPEC_TH_VLXSEGW : UNSPEC_TH_VLXSEGWU;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ return e.use_exact_insn (
+ code_for_pred_th_indexed_load (UNSPEC, e.vector_mode (), e.index_mode
()));
+ }
+};
+
+/* Implements th.vsxseg (b/h/w)[u].v codegen. */
+class th_vsxseg : public function_base {
+public:
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+
+ unsigned int call_properties (const function_instance &) const override {
+ return CP_WRITE_MEMORY;
+ }
+
+ bool can_be_overloaded_p (enum predication_type_index) const override {
+ return true;
+ }
+
+ rtx expand (function_expander &e) const override {
+ gcc_assert (TARGET_XTHEADVECTOR);
+ unsigned sew = GET_MODE_BITSIZE (GET_MODE_INNER (e.vector_mode ()));
+ int UNSPEC;
+ switch (sew)
+ {
+ case 8:
+ UNSPEC = UNSPEC_TH_VLXSEGB;
+ break;
+ case 16:
+ UNSPEC = UNSPEC_TH_VLXSEGH;
+ break;
+ case 32:
+ UNSPEC = UNSPEC_TH_VLXSEGW;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ return e.use_exact_insn (code_for_pred_th_indexed_store (
+ UNSPEC, e.vector_mode (), e.index_mode ()));
+ }
+};
+
/* Xtheadvector */
static CONSTEXPR const th_vlseg<true> th_vlseg_obj;
static CONSTEXPR const th_vlseg<false> th_vlsegu_obj;
@@ -200,6 +272,9 @@ static CONSTEXPR const th_vsseg th_vsseg_obj;
static CONSTEXPR const th_vlsseg<true> th_vlsseg_obj;
static CONSTEXPR const th_vlsseg<false> th_vlssegu_obj;
static CONSTEXPR const th_vssseg th_vssseg_obj;
+static CONSTEXPR const th_vlxseg<true> th_vlxseg_obj;
+static CONSTEXPR const th_vlxseg<false> th_vlxsegu_obj;
+static CONSTEXPR const th_vsxseg th_vsxseg_obj;
/* Declare the function base NAME, pointing it to an instance
of class <NAME>_obj. */
@@ -213,4 +288,7 @@ BASE (th_vsseg)
BASE (th_vlsseg)
BASE (th_vlssegu)
BASE (th_vssseg)
+BASE (th_vlxseg)
+BASE (th_vlxsegu)
+BASE (th_vsxseg)
} // end namespace riscv_vector
diff --git a/gcc/config/riscv/thead-vector-builtins-bases.h
b/gcc/config/riscv/thead-vector-builtins-bases.h
index e77aed5c259..35b4ccb379c 100644
--- a/gcc/config/riscv/thead-vector-builtins-bases.h
+++ b/gcc/config/riscv/thead-vector-builtins-bases.h
@@ -32,6 +32,9 @@ extern const function_base *const th_vsseg;
extern const function_base *const th_vlsseg;
extern const function_base *const th_vlssegu;
extern const function_base *const th_vssseg;
+extern const function_base *const th_vlxseg;
+extern const function_base *const th_vlxsegu;
+extern const function_base *const th_vsxseg;
}
} // end namespace riscv_vector
diff --git a/gcc/config/riscv/thead-vector-builtins-functions.def
b/gcc/config/riscv/thead-vector-builtins-functions.def
index b985746f8bd..5cd6f279a32 100644
--- a/gcc/config/riscv/thead-vector-builtins-functions.def
+++ b/gcc/config/riscv/thead-vector-builtins-functions.def
@@ -40,6 +40,9 @@ DEF_RVV_FUNCTION (th_vsseg, th_seg_loadstore, none_m_preds,
th_tuple_v_int_scala
DEF_RVV_FUNCTION (th_vlsseg, th_seg_loadstore, full_preds,
th_tuple_v_sint_scalar_const_ptr_ptrdiff_ops)
DEF_RVV_FUNCTION (th_vlssegu, th_seg_loadstore, full_preds,
th_tuple_v_uint_scalar_const_ptr_ptrdiff_ops)
DEF_RVV_FUNCTION (th_vssseg, th_seg_loadstore, none_m_preds,
th_tuple_v_int_scalar_ptr_ptrdiff_ops)
+DEF_RVV_FUNCTION (th_vlxseg, th_seg_loadstore, full_preds,
th_tuple_v_sint_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (th_vlxsegu, th_seg_loadstore, full_preds,
th_tuple_v_uint_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (th_vsxseg, th_seg_loadstore, none_m_preds,
th_tuple_v_int_scalar_ptr_index_ops)
#undef REQUIRED_EXTENSIONS
diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md
index 7ba06c6ab5b..c9cedcfc08d 100644
--- a/gcc/config/riscv/thead-vector.md
+++ b/gcc/config/riscv/thead-vector.md
@@ -39,6 +39,13 @@ (define_c_enum "unspec" [
UNSPEC_TH_VLSSEGHU
UNSPEC_TH_VLSSEGW
UNSPEC_TH_VLSSEGWU
+
+ UNSPEC_TH_VLXSEGB
+ UNSPEC_TH_VLXSEGBU
+ UNSPEC_TH_VLXSEGH
+ UNSPEC_TH_VLXSEGHU
+ UNSPEC_TH_VLXSEGW
+ UNSPEC_TH_VLXSEGWU
])
(define_int_iterator UNSPEC_TH_VLMEM_OP [
@@ -71,6 +78,12 @@ (define_int_iterator UNSPEC_TH_VLSSEGMEM_OP[
UNSPEC_TH_VLSSEGW UNSPEC_TH_VLSSEGWU
])
+(define_int_iterator UNSPEC_TH_VLXSEGMEM_OP[
+ UNSPEC_TH_VLXSEGB UNSPEC_TH_VLXSEGBU
+ UNSPEC_TH_VLXSEGH UNSPEC_TH_VLXSEGHU
+ UNSPEC_TH_VLXSEGW UNSPEC_TH_VLXSEGWU
+])
+
(define_int_attr vlmem_op_attr [
(UNSPEC_TH_VLB "b") (UNSPEC_TH_VLBU "bu")
(UNSPEC_TH_VLH "h") (UNSPEC_TH_VLHU "hu")
@@ -90,6 +103,9 @@ (define_int_attr vlmem_op_attr [
(UNSPEC_TH_VLSSEGB "b") (UNSPEC_TH_VLSSEGBU "bu")
(UNSPEC_TH_VLSSEGH "h") (UNSPEC_TH_VLSSEGHU "hu")
(UNSPEC_TH_VLSSEGW "w") (UNSPEC_TH_VLSSEGWU "wu")
+ (UNSPEC_TH_VLXSEGB "b") (UNSPEC_TH_VLXSEGBU "bu")
+ (UNSPEC_TH_VLXSEGH "h") (UNSPEC_TH_VLXSEGHU "hu")
+ (UNSPEC_TH_VLXSEGW "w") (UNSPEC_TH_VLXSEGWU "wu")
])
(define_int_attr vlmem_order_attr [
@@ -134,6 +150,12 @@ (define_int_iterator UNSPEC_TH_VSSSEGMEM_OP[
UNSPEC_TH_VLSSEGW
])
+(define_int_iterator UNSPEC_TH_VSXSEGMEM_OP[
+ UNSPEC_TH_VLXSEGB
+ UNSPEC_TH_VLXSEGH
+ UNSPEC_TH_VLXSEGW
+])
+
(define_mode_iterator V_VLS_VT [V VLS VT])
(define_mode_iterator V_VB_VLS_VT [V VB VLS VT])
@@ -544,3 +566,41 @@ (define_insn "@pred_th_strided_store<vlmem_op_attr><mode>"
"vssseg<nf><vlmem_op_attr>.v\t%3,(%z1),%z2%p0"
[(set_attr "type" "vssegts")
(set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_th_indexed_load<vlmem_op_attr><VT:mode><VI:mode>"
+ [(set (match_operand:VT 0 "register_operand" "=&vr, &vr")
+ (if_then_else:VT
+ (unspec:<VT:VM>
+ [(match_operand:<VT: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)] UNSPEC_TH_VLXSEGMEM_OP)
+ (unspec:VT
+ [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ")
+ (mem:BLK (scratch))
+ (match_operand:VI 4 "register_operand" " vr, vr")]
UNSPEC_TH_VLXSEGMEM_OP)
+ (match_operand:VT 2 "vector_merge_operand" " vu, 0")))]
+ "TARGET_XTHEADVECTOR"
+ "vlxseg<nf><vlmem_op_attr>.v\t%0,(%z3),%4%p1"
+ [(set_attr "type" "vlsegdux")
+ (set_attr "mode" "<VT:MODE>")])
+
+(define_insn "@pred_th_indexed_store<vlmem_op_attr><VT:mode><VI:mode>"
+ [(set (mem:BLK (scratch))
+ (unspec:BLK
+ [(unspec:<VT:VM>
+ [(match_operand:<VT:VM> 0 "vector_mask_operand" "vmWc1")
+ (match_operand 4 "vector_length_operand" " rK")
+ (match_operand 5 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_TH_VSXSEGMEM_OP)
+ (match_operand 1 "pmode_reg_or_0_operand" " rJ")
+ (match_operand:VI 2 "register_operand" " vr")
+ (match_operand:VT 3 "register_operand" " vr")]
UNSPEC_TH_VSXSEGMEM_OP))]
+ "TARGET_XTHEADVECTOR"
+ "vsxseg<nf><vlmem_op_attr>.v\t%3,(%z1),%2%p0"
+ [(set_attr "type" "vssegtux")
+ (set_attr "mode" "<VT:MODE>")])
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxseg-vsxseg.c
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxseg-vsxseg.c
new file mode 100644
index 00000000000..ab05b0ff699
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxseg-vsxseg.c
@@ -0,0 +1,125 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** li\s+[a-x0-9]+,4
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vlxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vsxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** ret
+*/
+void f1 (void * in, void *out, vuint16m1_t index)
+{
+ vint16m1x2_t v = __riscv_th_vlxseg2h_v_i16m1x2 (in, index, 4);
+ vint16m1x2_t v2 = __riscv_th_vlxseg2h_v_i16m1x2_tu (v, in, index, 4);
+ vint16m1_t v2_0 = __riscv_vget_i16m1 (v2, 0);
+ vint16m1_t v2_1 = __riscv_vget_i16m1 (v2, 1);
+ vint16m1_t v3_0 = __riscv_vadd_vv_i16m1 (v2_0, v2_0, 4);
+ vint16m1_t v3_1 = __riscv_vadd_vv_i16m1 (v2_1, v2_1, 4);
+ vint16m1_t v4_0 = __riscv_vadd_vv_i16m1 (v3_0, v2_0, 4);
+ vint16m1_t v4_1 = __riscv_vadd_vv_i16m1 (v3_1, v2_1, 4);
+ vint16m1x2_t v4 = __riscv_vset (v4, 0, v4_0);
+ v4 = __riscv_vset (v4, 1, v4_1);
+ __riscv_th_vsxseg2h_v_i16m1x2 (out, index, v4, 4);
+}
+
+/*
+** f2:
+** th\.vsetvli\s+zero,zero,e8,m1
+** th\.vle\.v\s+v[0-9]+,0\([a-x0-9]+\)
+** li\s+[a-x0-9]+,4
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+,v[0-9]+\.t
+** th\.vlxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vsxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** ret
+*/
+void f2 (void * in, void *out, vuint16m1_t index)
+{
+ vbool16_t mask = *(vbool16_t*)in;
+ asm volatile ("":::"memory");
+ vint16m1x2_t v = __riscv_th_vlxseg2h_v_i16m1x2 (in, index, 4);
+ vint16m1x2_t v2 = __riscv_th_vlxseg2h_v_i16m1x2_m (mask, in, index, 4);
+ vint16m1_t v_0 = __riscv_vget_i16m1 (v, 0);
+ vint16m1_t v_1 = __riscv_vget_i16m1 (v, 1);
+ vint16m1_t v2_0 = __riscv_vget_i16m1 (v2, 0);
+ vint16m1_t v2_1 = __riscv_vget_i16m1 (v2, 1);
+ vint16m1_t v3_0 = __riscv_vadd_vv_i16m1_m (mask, v2_0, v_0, 4);
+ vint16m1_t v3_1 = __riscv_vadd_vv_i16m1_m (mask, v2_1, v_1, 4);
+ vint16m1_t v4_0 = __riscv_vadd_vv_i16m1_m (mask, v3_0, v2_0, 4);
+ vint16m1_t v4_1 = __riscv_vadd_vv_i16m1_m (mask, v3_1, v2_1, 4);
+ vint16m1x2_t v4 = __riscv_vset (v4, 0, v4_0);
+ v4 = __riscv_vset (v4, 1, v4_1);
+ __riscv_th_vsxseg2h_v_i16m1x2 (out, index, v4, 4);
+}
+
+/*
+** f3:
+** th\.vsetvli\s+zero,zero,e8,m1
+** th\.vle\.v\s+v[0-9]+,0\([a-x0-9]+\)
+** li\s+[a-x0-9]+,4
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vsetvli\s+[a-x0-9]+,zero,e16,m1
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+,v[0-9]+\.t
+** th\.vsetvli\s+[a-x0-9]+,zero,e16,m1
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vsxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** ret
+*/
+void f3 (void * in, void *out, vuint16m1_t index)
+{
+ vbool16_t mask = *(vbool16_t*)in;
+ asm volatile ("":::"memory");
+ vint16m1x2_t v = __riscv_th_vlxseg2h_v_i16m1x2 (in, index, 4);
+ vint16m1x2_t v2 = __riscv_th_vlxseg2h_v_i16m1x2_tumu (mask, v, in, index,
4);
+ vint16m1_t v2_0 = __riscv_vget_i16m1 (v2, 0);
+ vint16m1_t v2_1 = __riscv_vget_i16m1 (v2, 1);
+ vint16m1_t v3_0 = __riscv_vadd_vv_i16m1_tumu (mask, v3_0, v2_0, v2_0, 4);
+ vint16m1_t v3_1 = __riscv_vadd_vv_i16m1_tumu (mask, v3_1, v2_1, v2_1, 4);
+ vint16m1_t v4_0 = __riscv_vadd_vv_i16m1_tumu (mask, v4_0, v3_0, v2_0, 4);
+ vint16m1_t v4_1 = __riscv_vadd_vv_i16m1_tumu (mask, v4_1, v3_1, v2_1, 4);
+ vint16m1x2_t v4 = __riscv_vset (v4, 0, v4_0);
+ v4 = __riscv_vset (v4, 1, v4_1);
+ __riscv_th_vsxseg2h_v_i16m1x2 (out, index, v4, 4);
+}
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxsegu-vsxseg.c
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxsegu-vsxseg.c
new file mode 100644
index 00000000000..b085de74061
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlxsegu-vsxseg.c
@@ -0,0 +1,125 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** li\s+[a-x0-9]+,4
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2hu\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vlxseg2hu\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vsxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** ret
+*/
+void f1 (void * in, void *out, vuint16m1_t index)
+{
+ vuint16m1x2_t v = __riscv_th_vlxseg2hu_v_u16m1x2 (in, index, 4);
+ vuint16m1x2_t v2 = __riscv_th_vlxseg2hu_v_u16m1x2_tu (v, in, index, 4);
+ vuint16m1_t v2_0 = __riscv_vget_u16m1 (v2, 0);
+ vuint16m1_t v2_1 = __riscv_vget_u16m1 (v2, 1);
+ vuint16m1_t v3_0 = __riscv_vadd_vv_u16m1 (v2_0, v2_0, 4);
+ vuint16m1_t v3_1 = __riscv_vadd_vv_u16m1 (v2_1, v2_1, 4);
+ vuint16m1_t v4_0 = __riscv_vadd_vv_u16m1 (v3_0, v2_0, 4);
+ vuint16m1_t v4_1 = __riscv_vadd_vv_u16m1 (v3_1, v2_1, 4);
+ vuint16m1x2_t v4 = __riscv_vset (v4, 0, v4_0);
+ v4 = __riscv_vset (v4, 1, v4_1);
+ __riscv_th_vsxseg2h_v_u16m1x2 (out, index, v4, 4);
+}
+
+/*
+** f2:
+** th\.vsetvli\s+zero,zero,e8,m1
+** th\.vle\.v\s+v[0-9]+,0\([a-x0-9]+\)
+** li\s+[a-x0-9]+,4
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2hu\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+,v[0-9]+\.t
+** th\.vlxseg2hu\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vsxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** ret
+*/
+void f2 (void * in, void *out, vuint16m1_t index)
+{
+ vbool16_t mask = *(vbool16_t*)in;
+ asm volatile ("":::"memory");
+ vuint16m1x2_t v = __riscv_th_vlxseg2hu_v_u16m1x2 (in, index, 4);
+ vuint16m1x2_t v2 = __riscv_th_vlxseg2hu_v_u16m1x2_m (mask, in, index, 4);
+ vuint16m1_t v_0 = __riscv_vget_u16m1 (v, 0);
+ vuint16m1_t v_1 = __riscv_vget_u16m1 (v, 1);
+ vuint16m1_t v2_0 = __riscv_vget_u16m1 (v2, 0);
+ vuint16m1_t v2_1 = __riscv_vget_u16m1 (v2, 1);
+ vuint16m1_t v3_0 = __riscv_vadd_vv_u16m1_m (mask, v2_0, v_0, 4);
+ vuint16m1_t v3_1 = __riscv_vadd_vv_u16m1_m (mask, v2_1, v_1, 4);
+ vuint16m1_t v4_0 = __riscv_vadd_vv_u16m1_m (mask, v3_0, v2_0, 4);
+ vuint16m1_t v4_1 = __riscv_vadd_vv_u16m1_m (mask, v3_1, v2_1, 4);
+ vuint16m1x2_t v4 = __riscv_vset (v4, 0, v4_0);
+ v4 = __riscv_vset (v4, 1, v4_1);
+ __riscv_th_vsxseg2h_v_u16m1x2 (out, index, v4, 4);
+}
+
+/*
+** f3:
+** th\.vsetvli\s+zero,zero,e8,m1
+** th\.vle\.v\s+v[0-9]+,0\([a-x0-9]+\)
+** li\s+[a-x0-9]+,4
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2hu\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** th\.vsetvli\s+[a-x0-9]+,zero,e16,m1
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vlxseg2hu\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+,v[0-9]+\.t
+** th\.vsetvli\s+[a-x0-9]+,zero,e16,m1
+** th\.vmv\.v\.i\s+v[0-9]+,0
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vadd\.vv\s+v[0-9]+,v[0-9]+,v[0-9]+,v[0-9]+\.t
+** th\.vsetvli\s+zero,zero,e16,m1
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vmv\.v\.v\s+v[0-9]+,v[0-9]+
+** th\.vsetvli\s+zero,[a-x0-9]+,e16,m1
+** th\.vsxseg2h\.v\s+v[0-9]+,\([a-x0-9]+\),v[0-9]+
+** ret
+*/
+void f3 (void * in, void *out, vuint16m1_t index)
+{
+ vbool16_t mask = *(vbool16_t*)in;
+ asm volatile ("":::"memory");
+ vuint16m1x2_t v = __riscv_th_vlxseg2hu_v_u16m1x2 (in, index, 4);
+ vuint16m1x2_t v2 = __riscv_th_vlxseg2hu_v_u16m1x2_tumu (mask, v, in,
index, 4);
+ vuint16m1_t v2_0 = __riscv_vget_u16m1 (v2, 0);
+ vuint16m1_t v2_1 = __riscv_vget_u16m1 (v2, 1);
+ vuint16m1_t v3_0 = __riscv_vadd_vv_u16m1_tumu (mask, v3_0, v2_0, v2_0, 4);
+ vuint16m1_t v3_1 = __riscv_vadd_vv_u16m1_tumu (mask, v3_1, v2_1, v2_1, 4);
+ vuint16m1_t v4_0 = __riscv_vadd_vv_u16m1_tumu (mask, v4_0, v3_0, v2_0, 4);
+ vuint16m1_t v4_1 = __riscv_vadd_vv_u16m1_tumu (mask, v4_1, v3_1, v2_1, 4);
+ vuint16m1x2_t v4 = __riscv_vset (v4, 0, v4_0);
+ v4 = __riscv_vset (v4, 1, v4_1);
+ __riscv_th_vsxseg2h_v_u16m1x2 (out, index, v4, 4);
+}
\ No newline at end of file
--
2.47.1