Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch Status 29598-ReRePATCH_v5_RISCV_Add_support_for_xtheadvectorspecific_intrinsics-1 #1175

Closed
github-actions bot opened this issue Jan 12, 2024 · 2 comments
Labels
apply-failure Patch failed to apply to baseline and tip of tree linter-failure Lint failed

Comments

@github-actions
Copy link

Precommit CI Run information

Logs can be found in the associated Github Actions run: https://github.com/ewlu/gcc-precommit-ci/actions/runs/7497630129

Patch information

Applied patches: 1 -> 1
Associated series: https://patchwork.sourceware.org/project/gcc/list/?series=29598
Last patch applied: https://patchwork.sourceware.org/project/gcc/patch/9e66a4f4-aede-4635-86a7-704e38d12969.cooper.joshua@linux.alibaba.com/
Patch id: 83956

Build Targets

Some targets are built as multilibs. If a build target ends with multilib, please refer to the table below to see all the targets within that multilib.

Target name -march string
newlib-rv64gc-lp64d-multilib rv32gc-ilp32d, rv64gc-lp64d
newlib-rv64gcv-lp64d-multilib rv64gcv-lp64d
linux-rv64gcv-lp64d-multilib rv32gcv-ilp32d, rv64gcv-lp64d

Target Information

Target Shorthand -march string
Bitmanip gc_zba_zbb_zbc_zbs

Notes

Testsuite results use a more lenient allowlist to reduce error reporting with flakey tests. Please take a look at the current allowlist.
Results come from a sum file comparator. Each patch is applied to a well known, non-broken baseline taken from our
gcc postcommit framework (here) which runs the full gcc testsuite every 6 hours.
If you have any questions or encounter any issues which may seem like false-positives, please contact us at patchworks-ci@rivosinc.com

Copy link
Author

github-actions bot commented Jan 12, 2024

Lint Status

The following issues have been found with 29598-ReRePATCH_v5_RISCV_Add_support_for_xtheadvectorspecific_intrinsics-1 using gcc's ./contrib/check_GNU_style.py.
Please use your best judgement when resolving these issues. These are only warnings and do not need to be resolved in order to merge your patch.
If any of these warnings seem like false-positives that could be guarded against please contact me: patchworks-ci@rivosinc.com.

Traceback (most recent call last):
  File "./gcc/contrib/check_GNU_style.py", line 45, in <module>
    main()
  File "./gcc/contrib/check_GNU_style.py", line 43, in main
    check_GNU_style_file(diff_file, format)
  File "/home/runner/work/gcc-precommit-ci/gcc-precommit-ci/riscv-gnu-toolchain/gcc/contrib/check_GNU_style_lib.py", line 279, in check_GNU_style_file
    patch = PatchSet(file)
  File "/home/runner/.local/lib/python3.8/site-packages/unidiff/patch.py", line 462, in __init__
    self._parse(data, encoding=encoding, metadata_only=metadata_only)
  File "/home/runner/.local/lib/python3.8/site-packages/unidiff/patch.py", line 552, in _parse
    current_file._parse_hunk(line, diff, encoding, metadata_only)
  File "/home/runner/.local/lib/python3.8/site-packages/unidiff/patch.py", line 318, in _parse_hunk
    raise UnidiffParseError(
unidiff.errors.UnidiffParseError: Hunk diff line expected: @@ -2603,6 +2680,37 @@ static CONSTEXPR const seg_indexed_load<UNSPEC_ORDERED> vloxseg_obj;

Additional information

Copy link
Author

github-actions bot commented Jan 12, 2024

Apply Status

Target Status
Baseline hash: gcc-mirror/gcc@65e2c93 Failed
Tip of tree hash: gcc-mirror/gcc@75ed465 Failed

Command

> git am ../patches/*.patch --whitespace=fix -q --3way --empty=drop

Output

error: corrupt patch at line 113
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0001 Re:Re:[PATCH v5] RISC-V: Add support for xtheadvector-specific intrinsics.
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
---
 .../riscv/riscv-vector-builtins-bases.cc | 139 ++++++++++
 .../riscv/riscv-vector-builtins-bases.h | 31 +++
 .../riscv/riscv-vector-builtins-shapes.cc | 160 +++++++++++
 .../riscv/riscv-vector-builtins-shapes.h | 3 +
 gcc/config/riscv/riscv-vector-builtins.cc | 70 +++++
 gcc/config/riscv/riscv-vector-builtins.h | 3 +
 gcc/config/riscv/t-riscv | 1 +
 .../riscv/thead-vector-builtins-functions.def | 39 +++
 gcc/config/riscv/thead-vector.md | 250 ++++++++++++++++++
 .../riscv/rvv/xtheadvector/vlb-vsb.c | 68 +++++
 .../riscv/rvv/xtheadvector/vlbu-vsb.c | 68 +++++
 .../riscv/rvv/xtheadvector/vlh-vsh.c | 68 +++++
 .../riscv/rvv/xtheadvector/vlhu-vsh.c | 68 +++++
 .../riscv/rvv/xtheadvector/vlw-vsw.c | 68 +++++
 .../riscv/rvv/xtheadvector/vlwu-vsw.c | 68 +++++
 15 files changed, 1104 insertions(+)
 create mode 100644 gcc/config/riscv/thead-vector-builtins-functions.def
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlbu-vsb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlh-vsh.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlhu-vsh.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlw-vsw.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlwu-vsw.c

diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 1aa6e3c6665..b6f6e4ff37e 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -2141,6 +2141,83 @@ public:
 }
 };
+/* Implements
+ * th.vl(b/h/w)[u].v/th.vs(b/h/w)[u].v/th.vls(b/h/w)[u].v/th.vss(b/h/w)[u].v/
+ * th.vlx(b/h/w)[u].v/th.vs[u]x(b/h/w).v
+ * codegen. */
+template<bool STORE_P, lst_type LST_TYPE, int UNSPEC>
+class th_loadstore_width : public function_base
+{
+public:
+ bool apply_tail_policy_p () const override { return !STORE_P; }
+ bool apply_mask_policy_p () const override { return !STORE_P; }
+
+ unsigned int call_properties (const function_instance &) const override
+ {
+ if (STORE_P)
+ return CP_WRITE_MEMORY;
+ else
+ return CP_READ_MEMORY;
+ }
+
+ bool can_be_overloaded_p (enum predication_type_index pred) const override
+ {
+ if (STORE_P || LST_TYPE == LST_INDEXED)
+ return true;
+ return pred != PRED_TYPE_none;
+ }
+
+ rtx expand (function_expander &e) const override
+ {
+ gcc_assert (TARGET_XTHEADVECTOR);
+ if (LST_TYPE == LST_INDEXED)
+ {
+ if (STORE_P)
+ return e.use_exact_insn (
+ code_for_pred_indexed_store_width (UNSPEC, UNSPEC,
+ e.vector_mode ()));
+ else
+ return e.use_exact_insn (
+ code_for_pred_indexed_load_width (UNSPEC, e.vector_mode ()));
+ }
+ else if (LST_TYPE == LST_STRIDED)
+ {
+ if (STORE_P)
+ return e.use_contiguous_store_insn (
+ code_for_pred_strided_store_width (UNSPEC, e.vector_mode ()));
+ else
+ return e.use_contiguous_load_insn (
+ code_for_pred_strided_load_width (UNSPEC, e.vector_mode ()));
+ }
+ else
+ {
+ if (STORE_P)
+ return e.use_contiguous_store_insn (
+ code_for_pred_store_width (UNSPEC, e.vector_mode ()));
+ else
+ return e.use_contiguous_load_insn (
+ code_for_pred_mov_width (UNSPEC, e.vector_mode ()));
+ }
+ }
+};
+
+/* Implements vext.x.v. */
+class th_extract : public function_base
+{
+public:
+ bool apply_vl_p () const override { return false; }
+ bool apply_tail_policy_p () const override { return false; }
+ bool apply_mask_policy_p () const override { return false; }
+ bool use_mask_predication_p () const override { return false; }
+ bool has_merge_operand_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ gcc_assert (TARGET_XTHEADVECTOR);
+ return e.use_exact_insn (code_for_pred_th_extract (e.vector_mode ()));
+ }
+};
+
 /* Below implements are vector crypto */
 /* Implements vandn.[vv,vx] */
 class vandn : public function_base
@@ -2603,6 +2680,37 @@ static CONSTEXPR const seg_indexed_load<UNSPEC_ORDERED> vloxseg_obj;
 static CONSTEXPR const seg_indexed_store<UNSPEC_UNORDERED> vsuxseg_obj;
 static CONSTEXPR const seg_indexed_store<UNSPEC_ORDERED> vsoxseg_obj;
 static CONSTEXPR const vlsegff vlsegff_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLB> vlb_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLBU> vlbu_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLH> vlh_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLHU> vlhu_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLW> vlw_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_UNIT_STRIDE, UNSPEC_TH_VLWU> vlwu_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_UNIT_STRIDE, UNSPEC_TH_VLB> vsb_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_UNIT_STRIDE, UNSPEC_TH_VLH> vsh_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_UNIT_STRIDE, UNSPEC_TH_VLW> vsw_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSB> vlsb_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSBU> vlsbu_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSH> vlsh_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSHU> vlshu_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSW> vlsw_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_STRIDED, UNSPEC_TH_VLSWU> vlswu_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_STRIDED, UNSPEC_TH_VLSB> vssb_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_STRIDED, UNSPEC_TH_VLSH> vssh_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_STRIDED, UNSPEC_TH_VLSW> vssw_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXB> vlxb_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXBU> vlxbu_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXH> vlxh_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXHU> vlxhu_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXW> vlxw_obj;
+static CONSTEXPR const th_loadstore_width<false, LST_INDEXED, UNSPEC_TH_VLXWU> vlxwu_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VLXB> vsxb_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VLXH> vsxh_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VLXW> vsxw_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VSUXB> vsuxb_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VSUXH> vsuxh_obj;
+static CONSTEXPR const th_loadstore_width<true, LST_INDEXED, UNSPEC_TH_VSUXW> vsuxw_obj;
+static CONSTEXPR const th_extract vext_x_v_obj;
 /* Crypto Vector */
 static CONSTEXPR const vandn vandn_obj;
@@ -2894,6 +3002,37 @@ BASE (vloxseg)
 BASE (vsuxseg)
 BASE (vsoxseg)
 BASE (vlsegff)
+BASE (vlb)
+BASE (vlh)
+BASE (vlw)
+BASE (vlbu)
+BASE (vlhu)
+BASE (vlwu)
+BASE (vsb)
+BASE (vsh)
+BASE (vsw)
+BASE (vlsb)
+BASE (vlsh)
+BASE (vlsw)
+BASE (vlsbu)
+BASE (vlshu)
+BASE (vlswu)
+BASE (vssb)
+BASE (vssh)
+BASE (vssw)
+BASE (vlxb)
+BASE (vlxh)
+BASE (vlxw)
+BASE (vlxbu)
+BASE (vlxhu)
+BASE (vlxwu)
+BASE (vsxb)
+BASE (vsxh)
+BASE (vsxw)
+BASE (vsuxb)
+BASE (vsuxh)
+BASE (vsuxw)
+BASE (vext_x_v)
 /* Crypto vector */
 BASE (vandn)
 BASE (vbrev)
diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h b/gcc/config/riscv/riscv-vector-builtins-bases.h
index 87c7f43a423..1f2c94d3541 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.h
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
@@ -280,6 +280,37 @@ extern const function_base *const vloxseg;
 extern const function_base *const vsuxseg;
 extern const function_base *const vsoxseg;
 extern const function_base *const vlsegff;
+extern const function_base *const vlb;
+extern const function_base *const vlh;
+extern const function_base *const vlw;
+extern const function_base *const vlbu;
+extern const function_base *const vlhu;
+extern const function_base *const vlwu;
+extern const function_base *const vsb;
+extern const function_base *const vsh;
+extern const function_base *const vsw;
+extern const function_base *const vlsb;
+extern const function_base *const vlsh;
+extern const function_base *const vlsw;
+extern const function_base *const vlsbu;
+extern const function_base *const vlshu;
+extern const function_base *const vlswu;
+extern const function_base *const vssb;
+extern const function_base *const vssh;
+extern const function_base *const vssw;
+extern const function_base *const vlxb;
+extern const function_base *const vlxh;
+extern const function_base *const vlxw;
+extern const function_base *const vlxbu;
+extern const function_base *const vlxhu;
+extern const function_base *const vlxwu;
+extern const function_base *const vsxb;
+extern const function_base *const vsxh;
+extern const function_base *const vsxw;
+extern const function_base *const vsuxb;
+extern const function_base *const vsuxh;
+extern const function_base *const vsuxw;
+extern const function_base *const vext_x_v;
 /* Below function_base are Vectro Crypto*/
 extern const function_base *const vandn;
 extern const function_base *const vbrev;
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
index 1e4f4d53de6..8e90b17a94b 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
@@ -211,6 +211,146 @@ struct indexed_loadstore_def : public function_shape
 }
 };
+/* Add one function instance for GROUP, using operand suffix at index OI,
+ mode suffix at index PAIR && bi and predication suffix at index pred_idx. */
+static void
+build_th_loadstore (function_builder &b, const function_group_info &group,
+ unsigned int pred_idx, unsigned int vec_type_idx)
+{
+ auto_vec<tree, 5> argument_types;
+ function_instance function_instance (group.base_name, *group.base,
+ *group.shape,
+ group.ops_infos.types[vec_type_idx],
+ group.preds[pred_idx], &group.ops_infos);
+ tree return_type = group.ops_infos.ret.get_tree_type (
+ group.ops_infos.types[vec_type_idx].index);
+ b.allocate_argument_types (function_instance, argument_types);
+ b.apply_predication (function_instance, return_type, argument_types);
+
+ if (TARGET_XTHEADVECTOR && !check_type (return_type, argument_types))
+ return;
+
+ tree type = builtin_types[group.ops_infos.types[vec_type_idx].index].vector;
+ if (strstr (group.base_name, "l")
+ && strstr (group.base_name, "u")
+ && !TYPE_UNSIGNED (TREE_TYPE (type)))
+ return;
+
+ if (strstr (group.base_name, "l")
+ && !strstr (group.base_name, "u")
+ && TYPE_UNSIGNED (TREE_TYPE (type)))
+ return;
+
+ machine_mode mode = TYPE_MODE (type);
+ int sew = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
+ if (strstr (group.base_name, "h") && sew == 8)
+ return;
+
+ if (strstr (group.base_name, "w") && (sew == 8 || sew ==16))
+ return;
+
+ b.add_overloaded_function (function_instance, *group.shape);
+ b.add_unique_function (function_instance, (*group.shape), return_type,
+ argument_types);
+}
+
+/* th_loadstore_width_def class. */
+struct th_loadstore_width_def : public build_base
+{
+ void build (function_builder &b,
+ const function_group_info &group) const override
+ {
+ for (unsigned int pred_idx = 0; group.preds[pred_idx] != NUM_PRED_TYPES;
+ ++pred_idx)
+ {
+ for (unsigned int vec_type_idx = 0;
+ group.ops_infos.types[vec_type_idx].index != NUM_VECTOR_TYPES;
+ ++vec_type_idx)
+ {
+ build_th_loadstore (b, group, pred_idx, vec_type_idx);
+ }
+ }
+ }
+
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+ /* Return nullptr if it can not be overloaded. */
+ if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+ return nullptr;
+
+ b.append_name ("__riscv_th_");
+ b.append_name (instance.base_name);
+
+ /* vop_v --> vop_v_<type>. */
+ if (!overloaded_p)
+ {
+ /* vop --> vop_v. */
+ b.append_name (operand_suffixes[instance.op_info->op]);
+ /* vop_v --> vop_v_<type>. */
+ 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)
+ return b.finish_name ();
+ b.append_name (predication_suffixes[instance.pred]);
+ return b.finish_name ();
+ }
+};
+
+
+/* th_indexed_loadstore_width_def class. */
+struct th_indexed_loadstore_width_def : public function_shape
+{
+ void build (function_builder &b,
+ const function_group_info &group) const override
+ {
+ for (unsigned int pred_idx = 0; group.preds[pred_idx] != NUM_PRED_TYPES;
+ ++pred_idx)
+ {
+ for (unsigned int vec_type_idx = 0;
+ group.ops_infos.types[vec_type_idx].index != NUM_VECTOR_TYPES;
+ ++vec_type_idx)
+ {
+ tree index_type = group.ops_infos.args[1].get_tree_type (
+ group.ops_infos.types[vec_type_idx].index);
+ if (!index_type)
+ continue;
+ build_th_loadstore (b, group, pred_idx, vec_type_idx);
+ }
+ }
+ }
+
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+
+ /* Return nullptr if it can not be overloaded. */
+ if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
+ return nullptr;
+
+ b.append_name ("__riscv_th_");
+ b.append_name (instance.base_name);
+ /* vop_v --> vop_v_<type>. */
+ if (!overloaded_p)
+ {
+ /* vop --> vop_v. */
+ b.append_name (operand_suffixes[instance.op_info->op]);
+ /* vop_v --> vop_v_<type>. */
+ 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)
+ return b.finish_name ();
+ b.append_name (predication_suffixes[instance.pred]);
+ return b.finish_name ();
+ }
+};
+
 /* alu_def class. */
 struct alu_def : public build_base
 {
@@ -632,6 +772,23 @@ struct reduc_alu_def : public build_base
 }
 };
+/* th_extract_def class. */
+struct th_extract_def : public build_base
+{
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+ b.append_name ("__riscv_th_");
+ b.append_name (instance.base_name);
+
+ if (overloaded_p)
+ return b.finish_name ();
+ b.append_name (type_suffixes[instance.type.index].vector);
+ b.append_name (type_suffixes[instance.type.index].scalar);
+ return b.finish_name ();
+ }
+};
+
 /* scalar_move_def class. */
 struct scalar_move_def : public build_base
 {
@@ -1094,6 +1251,8 @@ SHAPE(vsetvl, vsetvl)
 SHAPE(vsetvl, vsetvlmax)
 SHAPE(loadstore, loadstore)
 SHAPE(indexed_loadstore, indexed_loadstore)
+SHAPE(th_loadstore_width, th_loadstore_width)
+SHAPE(th_indexed_loadstore_width, th_indexed_loadstore_width)
 SHAPE(alu, alu)
 SHAPE(alu_frm, alu_frm)
 SHAPE(widen_alu, widen_alu)
@@ -1106,6 +1265,7 @@ SHAPE(move, move)
 SHAPE(mask_alu, mask_alu)
 SHAPE(reduc_alu, reduc_alu)
 SHAPE(reduc_alu_frm, reduc_alu_frm)
+SHAPE(th_extract, th_extract)
 SHAPE(scalar_move, scalar_move)
 SHAPE(vundefined, vundefined)
 SHAPE(misc, misc)
diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.h b/gcc/config/riscv/riscv-vector-builtins-shapes.h
index ac2a28ce017..a7624d0fabd 100644
--- a/gcc/config/riscv/riscv-vector-builtins-shapes.h
+++ b/gcc/config/riscv/riscv-vector-builtins-shapes.h
@@ -28,6 +28,8 @@ extern const function_shape *const vsetvl;
 extern const function_shape *const vsetvlmax;
 extern const function_shape *const loadstore;
 extern const function_shape *const indexed_loadstore;
+extern const function_shape *const th_loadstore_width;
+extern const function_shape *const th_indexed_loadstore_width;
 extern const function_shape *const alu;
 extern const function_shape *const alu_frm;
 extern const function_shape *const widen_alu;
@@ -41,6 +43,7 @@ extern const function_shape *const mask_alu;
 extern const function_shape *const reduc_alu;
 extern const function_shape *const reduc_alu_frm;
 extern const function_shape *const scalar_move;
+extern const function_shape *const th_extract;
 extern const function_shape *const vundefined;
 extern const function_shape *const misc;
 extern const function_shape *const vset;
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 25e0b6e56de..44b9fec1898 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -934,6 +934,32 @@ static CONSTEXPR const rvv_arg_type_info ext_vcreate_args[]
 = {rvv_arg_type_info (RVV_BASE_vector),
 rvv_arg_type_info_end};
+/* A list of args for vector_type func (const scalar_type *, size_t)
+ * function. */
+static CONSTEXPR const rvv_arg_type_info scalar_const_ptr_size_args[]
+ = {rvv_arg_type_info (RVV_BASE_scalar_const_ptr),
+ rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (const scalar_type *, eew8_index_type)
+ * function. */
+static CONSTEXPR const rvv_arg_type_info scalar_const_ptr_index_args[]
+ = {rvv_arg_type_info (RVV_BASE_scalar_const_ptr),
+ rvv_arg_type_info (RVV_BASE_unsigned_vector), rvv_arg_type_info_end};
+
+/* A list of args for void func (scalar_type *, eew8_index_type, vector_type)
+ * function. */
+static CONSTEXPR const rvv_arg_type_info scalar_ptr_index_args[]
+ = {rvv_arg_type_info (RVV_BASE_scalar_ptr),
+ rvv_arg_type_info (RVV_BASE_unsigned_vector),
+ rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end};
+
+/* A list of args for void func (scalar_type *, size_t, vector_type)
+ * function. */
+static CONSTEXPR const rvv_arg_type_info scalar_ptr_size_args[]
+ = {rvv_arg_type_info (RVV_BASE_scalar_ptr),
+ rvv_arg_type_info (RVV_BASE_size), rvv_arg_type_info (RVV_BASE_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};
@@ -1455,6 +1481,14 @@ static CONSTEXPR const rvv_op_info iu_shift_vvv_ops
 rvv_arg_type_info (RVV_BASE_vector), /* Return type */
 shift_vv_args /* Args */};
+/* A static operand information for scalar_type func (vector_type, size_t)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_x_s_u_ops
+ = {iu_ops, /* Types */
+ OP_TYPE_vx, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_scalar), /* Return type */
+ v_size_args /* Args */};
+
 /* A static operand information for vector_type func (vector_type, size_t)
 * function registration. */
 static CONSTEXPR const rvv_op_info iu_shift_vvx_ops
@@ -2638,6 +2672,38 @@ static CONSTEXPR const rvv_op_info all_v_vcreate_lmul4_x2_ops
 rvv_arg_type_info (RVV_BASE_vlmul_ext_x2), /* Return type */
 ext_vcreate_args /* Args */};
+/* A static operand information for vector_type func (const scalar_type *,
+ * size_t) function registration. */
+static CONSTEXPR const rvv_op_info all_v_scalar_const_ptr_size_ops
+ = {all_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ scalar_const_ptr_size_args /* Args */};
+
+/* A static operand information for void func (scalar_type *, size_t,
+ * vector_type) function registration. */
+static CONSTEXPR const rvv_op_info all_v_scalar_ptr_size_ops
+ = {all_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_void), /* Return type */
+ scalar_ptr_size_args /* Args */};
+
+/* A static operand information for vector_type func (const scalar_type *,
+ * index_type) function registration. */
+static CONSTEXPR const rvv_op_info all_v_scalar_const_ptr_index_ops
+ = {all_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 all_v_scalar_ptr_index_ops
+ = {all_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_void), /* Return type */
+ scalar_ptr_index_args /* Args */};
+
 /* A static operand information for vector_type func (vector_type).
 Some ins just supports SEW=32, such as crypto vectol Zvkg extension.
 * function registration. */
@@ -2816,6 +2882,10 @@ static function_group_info function_groups[] = {
 #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \
 {#NAME, &bases::NAME, &shapes::SHAPE, PREDS, OPS_INFO, REQUIRED_EXTENSIONS},
 #include "riscv-vector-builtins-functions.def"
+#undef DEF_RVV_FUNCTION
+#define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \
+ {#NAME, &bases::NAME, &shapes::SHAPE, PREDS, OPS_INFO, REQUIRED_EXTENSIONS},
+#include "thead-vector-builtins-functions.def"
 };
 /* The RVV types, with their built-in
diff --git a/gcc/config/riscv/riscv-vector-builtins.h b/gcc/config/riscv/riscv-vector-builtins.h
index 54c8824ff92..22fed60b4c3 100644
--- a/gcc/config/riscv/riscv-vector-builtins.h
+++ b/gcc/config/riscv/riscv-vector-builtins.h
@@ -123,6 +123,7 @@ enum required_ext
 ZVKNHB_EXT, /* Crypto vector Zvknhb sub-ext */
 ZVKSED_EXT, /* Crypto vector Zvksed sub-ext */
 ZVKSH_EXT, /* Crypto vector Zvksh sub-ext */
+ XTHEADVECTOR_EXT, /* XTheadVector extension */
 };
 /* Enumerates the RVV operand types. */
@@ -252,6 +253,8 @@ struct function_group_info
 return TARGET_ZVKSED;
 case ZVKSH_EXT:
 return TARGET_ZVKSH;
+ case XTHEADVECTOR_EXT:
+ return TARGET_XTHEADVECTOR;
 default:
 gcc_unreachable ();
 }
diff --git a/gcc/config/riscv/t-riscv b/gcc/config/riscv/t-riscv
index 32de6b851c1..38494320d8b 100644
--- a/gcc/config/riscv/t-riscv
+++ b/gcc/config/riscv/t-riscv
@@ -1,6 +1,7 @@
 RISCV_BUILTINS_H = $(srcdir)/config/riscv/riscv-vector-builtins.h \
 $(srcdir)/config/riscv/riscv-vector-builtins.def \
 $(srcdir)/config/riscv/riscv-vector-builtins-functions.def \
+ $(srcdir)/config/riscv/thead-vector-builtins-functions.def \
 riscv-vector-type-indexer.gen.def
 riscv-builtins.o: $(srcdir)/config/riscv/riscv-builtins.cc $(CONFIG_H) \
diff --git a/gcc/config/riscv/thead-vector-builtins-functions.def b/gcc/config/riscv/thead-vector-builtins-functions.def
new file mode 100644
index 00000000000..fd3ba29bae9
--- /dev/null
+++ b/gcc/config/riscv/thead-vector-builtins-functions.def
@@ -0,0 +1,39 @@
+#ifndef DEF_RVV_FUNCTION
+#define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)
+#endif
+
+#define REQUIRED_EXTENSIONS XTHEADVECTOR_EXT
+DEF_RVV_FUNCTION (vlb, th_loadstore_width, full_preds, all_v_scalar_const_ptr_ops)
+DEF_RVV_FUNCTION (vlh, th_loadstore_width, full_preds, all_v_scalar_const_ptr_ops)
+DEF_RVV_FUNCTION (vlw, th_loadstore_width, full_preds, all_v_scalar_const_ptr_ops)
+DEF_RVV_FUNCTION (vlbu, th_loadstore_width, full_preds, all_v_scalar_const_ptr_ops)
+DEF_RVV_FUNCTION (vlhu, th_loadstore_width, full_preds, all_v_scalar_const_ptr_ops)
+DEF_RVV_FUNCTION (vlwu, th_loadstore_width, full_preds, all_v_scalar_const_ptr_ops)
+DEF_RVV_FUNCTION (vsb, th_loadstore_width, none_m_preds, all_v_scalar_ptr_ops)
+DEF_RVV_FUNCTION (vsh, th_loadstore_width, none_m_preds, all_v_scalar_ptr_ops)
+DEF_RVV_FUNCTION (vsw, th_loadstore_width, none_m_preds, all_v_scalar_ptr_ops)
+DEF_RVV_FUNCTION (vlsb, th_loadstore_width, full_preds, all_v_scalar_const_ptr_size_ops)
+DEF_RVV_FUNCTION (vlsh, th_loadstore_width, full_preds, all_v_scalar_const_ptr_size_ops)
+DEF_RVV_FUNCTION (vlsw, th_loadstore_width, full_preds, all_v_scalar_const_ptr_size_ops)
+DEF_RVV_FUNCTION (vlsbu, th_loadstore_width, full_preds, all_v_scalar_const_ptr_size_ops)
+DEF_RVV_FUNCTION (vlshu, th_loadstore_width, full_preds, all_v_scalar_const_ptr_size_ops)
+DEF_RVV_FUNCTION (vlswu, th_loadstore_width, full_preds, all_v_scalar_const_ptr_size_ops)
+DEF_RVV_FUNCTION (vssb, th_loadstore_width, none_m_preds, all_v_scalar_ptr_size_ops)
+DEF_RVV_FUNCTION (vssh, th_loadstore_width, none_m_preds, all_v_scalar_ptr_size_ops)
+DEF_RVV_FUNCTION (vssw, th_loadstore_width, none_m_preds, all_v_scalar_ptr_size_ops)
+DEF_RVV_FUNCTION (vlxb, th_indexed_loadstore_width, full_preds, all_v_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (vlxh, th_indexed_loadstore_width, full_preds, all_v_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (vlxw, th_indexed_loadstore_width, full_preds, all_v_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (vlxbu, th_indexed_loadstore_width, full_preds, all_v_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (vlxhu, th_indexed_loadstore_width, full_preds, all_v_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (vlxwu, th_indexed_loadstore_width, full_preds, all_v_scalar_const_ptr_index_ops)
+DEF_RVV_FUNCTION (vsxb, th_indexed_loadstore_width, none_m_preds, all_v_scalar_ptr_index_ops)
+DEF_RVV_FUNCTION (vsxh, th_indexed_loadstore_width, none_m_preds, all_v_scalar_ptr_index_ops)
+DEF_RVV_FUNCTION (vsxw, th_indexed_loadstore_width, none_m_preds, all_v_scalar_ptr_index_ops)
+DEF_RVV_FUNCTION (vsuxb, th_indexed_loadstore_width, none_m_preds, all_v_scalar_ptr_index_ops)
+DEF_RVV_FUNCTION (vsuxh, th_indexed_loadstore_width, none_m_preds, all_v_scalar_ptr_index_ops)
+DEF_RVV_FUNCTION (vsuxw, th_indexed_loadstore_width, none_m_preds, all_v_scalar_ptr_index_ops)
+DEF_RVV_FUNCTION (vext_x_v, th_extract, none_preds, iu_x_s_u_ops)
+#undef REQUIRED_EXTENSIONS
+
+#undef DEF_RVV_FUNCTION
diff --git a/gcc/config/riscv/thead-vector.md b/gcc/config/riscv/thead-vector.md
index 696b815252d..5fe9ba08c4e 100644
--- a/gcc/config/riscv/thead-vector.md
+++ b/gcc/config/riscv/thead-vector.md
@@ -1,7 +1,95 @@
 (define_c_enum "unspec" [
+ UNSPEC_TH_VLB
+ UNSPEC_TH_VLBU
+ UNSPEC_TH_VLH
+ UNSPEC_TH_VLHU
+ UNSPEC_TH_VLW
+ UNSPEC_TH_VLWU
+
+ UNSPEC_TH_VLSB
+ UNSPEC_TH_VLSBU
+ UNSPEC_TH_VLSH
+ UNSPEC_TH_VLSHU
+ UNSPEC_TH_VLSW
+ UNSPEC_TH_VLSWU
+
+ UNSPEC_TH_VLXB
+ UNSPEC_TH_VLXBU
+ UNSPEC_TH_VLXH
+ UNSPEC_TH_VLXHU
+ UNSPEC_TH_VLXW
+ UNSPEC_TH_VLXWU
+
+ UNSPEC_TH_VSUXB
+ UNSPEC_TH_VSUXH
+ UNSPEC_TH_VSUXW
+
 UNSPEC_TH_VWLDST
 ])
+(define_int_iterator UNSPEC_TH_VLMEM_OP [
+ UNSPEC_TH_VLB UNSPEC_TH_VLBU
+ UNSPEC_TH_VLH UNSPEC_TH_VLHU
+ UNSPEC_TH_VLW UNSPEC_TH_VLWU
+])
+
+(define_int_iterator UNSPEC_TH_VLSMEM_OP [
+ UNSPEC_TH_VLSB UNSPEC_TH_VLSBU
+ UNSPEC_TH_VLSH UNSPEC_TH_VLSHU
+ UNSPEC_TH_VLSW UNSPEC_TH_VLSWU
+])
+
+(define_int_iterator UNSPEC_TH_VLXMEM_OP [
+ UNSPEC_TH_VLXB UNSPEC_TH_VLXBU
+ UNSPEC_TH_VLXH UNSPEC_TH_VLXHU
+ UNSPEC_TH_VLXW UNSPEC_TH_VLXWU
+])
+
+(define_int_attr vlmem_op_attr [
+ (UNSPEC_TH_VLB "b") (UNSPEC_TH_VLBU "bu")
+ (UNSPEC_TH_VLH "h") (UNSPEC_TH_VLHU "hu")
+ (UNSPEC_TH_VLW "w") (UNSPEC_TH_VLWU "wu")
+ (UNSPEC_TH_VLSB "b") (UNSPEC_TH_VLSBU "bu")
+ (UNSPEC_TH_VLSH "h") (UNSPEC_TH_VLSHU "hu")
+ (UNSPEC_TH_VLSW "w") (UNSPEC_TH_VLSWU "wu")
+ (UNSPEC_TH_VLXB "b") (UNSPEC_TH_VLXBU "bu")
+ (UNSPEC_TH_VLXH "h") (UNSPEC_TH_VLXHU "hu")
+ (UNSPEC_TH_VLXW "w") (UNSPEC_TH_VLXWU "wu")
+ (UNSPEC_TH_VSUXB "b")
+ (UNSPEC_TH_VSUXH "h")
+ (UNSPEC_TH_VSUXW "w")
+])
+
+(define_int_attr vlmem_order_attr [
+ (UNSPEC_TH_VLXB "")
+ (UNSPEC_TH_VLXH "")
+ (UNSPEC_TH_VLXW "")
+ (UNSPEC_TH_VSUXB "u")
+ (UNSPEC_TH_VSUXH "u")
+ (UNSPEC_TH_VSUXW "u")
+])
+
+(define_int_iterator UNSPEC_TH_VSMEM_OP [
+ UNSPEC_TH_VLB
+ UNSPEC_TH_VLH
+ UNSPEC_TH_VLW
+])
+
+(define_int_iterator UNSPEC_TH_VSSMEM_OP [
+ UNSPEC_TH_VLSB
+ UNSPEC_TH_VLSH
+ UNSPEC_TH_VLSW
+])
+
+(define_int_iterator UNSPEC_TH_VSXMEM_OP [
+ UNSPEC_TH_VLXB
+ UNSPEC_TH_VLXH
+ UNSPEC_TH_VLXW
+ UNSPEC_TH_VSUXB
+ UNSPEC_TH_VSUXH
+ UNSPEC_TH_VSUXW
+])
+
 (define_mode_iterator V_VLS_VT [V VLS VT])
 (define_mode_iterator V_VB_VLS_VT [V VB VLS VT])
@@ -100,3 +188,165 @@
 }
 [(set_attr "type" "vldm,vstm,vmalu,vmalu,vmalu")
 (set_attr "mode" "<MODE>")])
+
+(define_expand "@pred_mov_width<vlmem_op_attr><mode>"
+ [(set (match_operand:V_VLS 0 "nonimmediate_operand")
+ (if_then_else:V_VLS
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand")
+ (match_operand 4 "vector_length_operand")
+ (match_operand 5 "const_int_operand")
+ (match_operand 6 "const_int_operand")
+ (match_operand 7 "const_int_operand")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_TH_VLMEM_OP)
+ (match_operand:V_VLS 3 "vector_move_operand")
+ (match_operand:V_VLS 2 "vector_merge_operand")))]
+ "TARGET_XTHEADVECTOR"
+ {})
+
+(define_insn_and_split "*pred_mov_width<vlmem_op_attr><mode>"
+ [(set (match_operand:V_VLS 0 "nonimmediate_operand" "=vr, vr, vd, m, vr, vr")
+ (if_then_else:V_VLS
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1, Wc1, vm, vmWc1, Wc1, Wc1")
+ (match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK, rK")
+ (match_operand 5 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 6 "const_int_operand" " i, i, i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_TH_VLMEM_OP)
+ (match_operand:V_VLS 3 "reg_or_mem_operand" " m, m, m, vr, vr, vr")
+ (match_operand:V_VLS 2 "vector_merge_operand" " 0, vu, vu, vu, vu, 0")))]
+ "(TARGET_XTHEADVECTOR
+ && (register_operand (operands[0], <MODE>mode)
+ || register_operand (operands[3], <MODE>mode)))"
+ "@
+ vl<vlmem_op_attr>.v\t%0,%3%p1
+ vl<vlmem_op_attr>.v\t%0,%3
+ vl<vlmem_op_attr>.v\t%0,%3,%1.t
+ vs<vlmem_op_attr>.v\t%3,%0%p1
+ vmv.v.v\t%0,%3
+ vmv.v.v\t%0,%3"
+ "&& riscv_vector::whole_reg_to_reg_move_p (operands, <MODE>mode, 7)"
+ [(set (match_dup 0) (match_dup 3))]
+ ""
+ [(set_attr "type" "vlde,vlde,vlde,vste,vimov,vimov")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_store_width<vlmem_op_attr><mode>"
+ [(set (match_operand:VI 0 "memory_operand" "+m")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+ (match_operand 3 "vector_length_operand" " rK")
+ (match_operand 4 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_TH_VSMEM_OP)
+ (match_operand:VI 2 "register_operand" " vr")
+ (match_dup 0)))]
+ "TARGET_XTHEADVECTOR"
+ "vs<vlmem_op_attr>.v\t%2,%0%p1"
+ [(set_attr "type" "vste")
+ (set_attr "mode" "<MODE>")
+ (set (attr "avl_type_idx") (const_int 4))
+ (set_attr "vl_op_idx" "3")])
+
+(define_insn "@pred_strided_load_width<vlmem_op_attr><mode>"
+ [(set (match_operand:VI 0 "register_operand" "=vr, vr, vd")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1, Wc1, vm")
+ (match_operand 5 "vector_length_operand" " rK, rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_TH_VLSMEM_OP)
+ (unspec:VI
+ [(match_operand:VI 3 "memory_operand" " m, m, m")
+ (match_operand 4 "pmode_reg_or_0_operand" " rJ, rJ, rJ")] UNSPEC_TH_VLSMEM_OP)
+ (match_operand:VI 2 "vector_merge_operand" " 0, vu, vu")))]
+ "TARGET_XTHEADVECTOR"
+ "vls<vlmem_op_attr>.v\t%0,%3,%z4%p1"
+ [(set_attr "type" "vlds")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_strided_store_width<vlmem_op_attr><mode>"
+ [(set (match_operand:VI 0 "memory_operand" "+m")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "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_VSSMEM_OP)
+ (unspec:VI
+ [(match_operand 2 "pmode_reg_or_0_operand" " rJ")
+ (match_operand:VI 3 "register_operand" " vr")] UNSPEC_TH_VSSMEM_OP)
+ (match_dup 0)))]
+ "TARGET_XTHEADVECTOR"
+ "vss<vlmem_op_attr>.v\t%3,%0,%z2%p1"
+ [(set_attr "type" "vsts")
+ (set_attr "mode" "<MODE>")
+ (set (attr "avl_type_idx") (const_int 5))])
+
+(define_insn "@pred_indexed_load_width<vlmem_op_attr><mode>"
+ [(set (match_operand:VI 0 "register_operand" "=vd, vr,vd, vr")
+ (if_then_else:VI
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1,vm,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK,rK, rK")
+ (match_operand 6 "const_int_operand" " i, i, i, i")
+ (match_operand 7 "const_int_operand" " i, i, i, i")
+ (match_operand 8 "const_int_operand" " i, i, i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_TH_VLXMEM_OP)
+ (unspec:VI
+ [(match_operand 3 "pmode_reg_or_0_operand" " rJ, rJ,rJ, rJ")
+ (mem:BLK (scratch))
+ (match_operand:VI 4 "register_operand" " vr, vr,vr, vr")] UNSPEC_TH_VLXMEM_OP)
+ (match_operand:VI 2 "vector_merge_operand" " vu, vu, 0, 0")))]
+ "TARGET_XTHEADVECTOR"
+ "vlx<vlmem_op_attr>.v\t%0,(%z3),%4%p1"
+ [(set_attr "type" "vldux")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_indexed_<vlmem_order_attr>store_width<vlmem_op_attr><mode>"
+ [(set (mem:BLK (scratch))
+ (unspec:BLK
+ [(unspec:<VM>
+ [(match_operand:<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_VSXMEM_OP)
+ (match_operand 1 "pmode_reg_or_0_operand" " rJ")
+ (match_operand:VI 2 "register_operand" " vr")
+ (match_operand:VI 3 "register_operand" " vr")] UNSPEC_TH_VSXMEM_OP))]
+ "TARGET_XTHEADVECTOR"
+ "vs<vlmem_order_attr>x<vlmem_op_attr>.v\t%3,(%z1),%2%p0"
+ [(set_attr "type" "vstux")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "@pred_th_extract<mode>"
+ [(set (match_operand:<VEL> 0 "register_operand")
+ (unspec:<VEL>
+ [(vec_select:<VEL>
+ (match_operand:V_VLSI 1 "register_operand")
+ (parallel [(match_operand:DI 2 "register_operand" "r")]))
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))]
+ "TARGET_XTHEADVECTOR"
+{})
+
+(define_insn "*pred_th_extract<mode>"
+ [(set (match_operand:<VEL> 0 "register_operand" "=r")
+ (unspec:<VEL>
+ [(vec_select:<VEL>
+ (match_operand:V_VLSI 1 "register_operand" "vr")
+ (parallel [(match_operand:DI 2 "register_operand" "r")]))
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))]
+ "TARGET_XTHEADVECTOR"
+ "vext.x.v\t%0,%1,%2"
+ [(set_attr "type" "vimovvx")
+ (set_attr "mode" "<MODE>")])
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
new file mode 100644
index 00000000000..3c12c124597
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlb-vsb.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** th.vsetivli\tzero,4,e32,m1,tu,ma
+** th.vlb\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlb\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
+** th.vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
+** th.vsb\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f1 (void * in, void *out)
+{
+ vint32m1_t v = __riscv_th_vlb_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlb_v_i32m1_tu (v, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vv_i32m1 (v2, v2, 4);
+ vint32m1_t v4 = __riscv_vadd_vv_i32m1_tu (v3, v2, v2, 4);
+ __riscv_th_vsb_v_i32m1 (out, v4, 4);
+}
+
+/*
+** f2:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,ta,ma
+** th.vlb.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
+** th.vadd\.vv\tv[1-9][0-9]?,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t
+** th.vsb.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f2 (void * in, void *out)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vint32m1_t v = __riscv_th_vlb_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlb_v_i32m1_m (mask, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vv_i32m1 (v2, v2, 4);
+ vint32m1_t v4 = __riscv_vadd_vv_i32m1_m (mask, v3, v3, 4);
+ __riscv_th_vsb_v_i32m1 (out, v4, 4);
+}
+
+/*
+** f3:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,tu,mu
+** th.vlb\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlb.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vv\tv[0-9]+,\s*v[0-9]+,\s*v[0-9]+
+** th.vadd\.vv\tv[1-9][0-9]?,\s*v[0-9]+,\s*v[0-9]+,\s*v0.t
+** th.vsb.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f3 (void * in, void *out)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vint32m1_t v = __riscv_th_vlb_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlb_v_i32m1_tumu (mask, v, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vv_i32m1 (v2, v2, 4);
+ vint32m1_t v4 = __riscv_vadd_vv_i32m1_tumu (mask, v3, v2, v2, 4);
+ __riscv_th_vsb_v_i32m1 (out, v4, 4);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlbu-vsb.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlbu-vsb.c
new file mode 100644
index 00000000000..30bef369375
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlbu-vsb.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** th.vsetivli\tzero,4,e32,m1,tu,ma
+** th.vlbu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlbu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vsb\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f1 (void * in, void *out, uint32_t x)
+{
+ vuint32m1_t v = __riscv_th_vlbu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlbu_v_u32m1_tu (v, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_tu (v3, v2, -16, 4);
+ __riscv_th_vsb_v_u32m1 (out, v4, 4);
+}
+
+/*
+** f2:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,ta,ma
+** th.vlbu.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsb.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f2 (void * in, void *out, uint32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vuint32m1_t v = __riscv_th_vlbu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlbu_v_u32m1_m (mask, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_m (mask, v3, -16, 4);
+ __riscv_th_vsb_v_u32m1 (out, v4, 4);
+}
+
+/*
+** f3:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,tu,mu
+** th.vlbu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlbu.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsb.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f3 (void * in, void *out, uint32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vuint32m1_t v = __riscv_th_vlbu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlbu_v_u32m1_tumu (mask, v, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_tumu (mask, v3, v2, -16, 4);
+ __riscv_th_vsb_v_u32m1 (out, v4, 4);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlh-vsh.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlh-vsh.c
new file mode 100644
index 00000000000..3c8b5ccc16b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlh-vsh.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** th.vsetivli\tzero,4,e32,m1,tu,ma
+** th.vlh\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlh\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vsh\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f1 (void * in, void *out, int32_t x)
+{
+ vint32m1_t v = __riscv_th_vlh_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlh_v_i32m1_tu (v, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vx_i32m1 (v2, -16, 4);
+ vint32m1_t v4 = __riscv_vadd_vx_i32m1_tu (v3, v2, -16, 4);
+ __riscv_th_vsh_v_i32m1 (out, v4, 4);
+}
+
+/*
+** f2:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,ta,ma
+** th.vlh.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsh.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f2 (void * in, void *out, int32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vint32m1_t v = __riscv_th_vlh_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlh_v_i32m1_m (mask, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vx_i32m1 (v2, -16, 4);
+ vint32m1_t v4 = __riscv_vadd_vx_i32m1_m (mask, v3, -16, 4);
+ __riscv_th_vsh_v_i32m1 (out, v4, 4);
+}
+
+/*
+** f3:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,tu,mu
+** th.vlh\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlh.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsh.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f3 (void * in, void *out, int32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vint32m1_t v = __riscv_th_vlh_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlh_v_i32m1_tumu (mask, v, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vx_i32m1 (v2, -16, 4);
+ vint32m1_t v4 = __riscv_vadd_vx_i32m1_tumu (mask, v3, v2, -16, 4);
+ __riscv_th_vsh_v_i32m1 (out, v4, 4);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlhu-vsh.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlhu-vsh.c
new file mode 100644
index 00000000000..b7c00404f18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlhu-vsh.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** th.vsetivli\tzero,4,e32,m1,tu,ma
+** th.vlhu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlhu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vsh\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f1 (void * in, void *out, uint32_t x)
+{
+ vuint32m1_t v = __riscv_th_vlhu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlhu_v_u32m1_tu (v, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_tu (v3, v2, -16, 4);
+ __riscv_th_vsh_v_u32m1 (out, v4, 4);
+}
+
+/*
+** f2:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,ta,ma
+** th.vlhu.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsh.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f2 (void * in, void *out, uint32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vuint32m1_t v = __riscv_th_vlhu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlhu_v_u32m1_m (mask, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_m (mask, v3, -16, 4);
+ __riscv_th_vsh_v_u32m1 (out, v4, 4);
+}
+
+/*
+** f3:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,tu,mu
+** th.vlhu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlhu.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsh.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f3 (void * in, void *out, uint32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vuint32m1_t v = __riscv_th_vlhu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlhu_v_u32m1_tumu (mask, v, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_tumu (mask, v3, v2, -16, 4);
+ __riscv_th_vsh_v_u32m1 (out, v4, 4);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlw-vsw.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlw-vsw.c
new file mode 100644
index 00000000000..17a53012acf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlw-vsw.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** th.vsetivli\tzero,4,e32,m1,tu,ma
+** th.vlw\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlw\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
+** th.vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
+** th.vsw\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f1 (void * in, void *out, int32_t x)
+{
+ vint32m1_t v = __riscv_th_vlw_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlw_v_i32m1_tu (v, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vx_i32m1 (v2, x, 4);
+ vint32m1_t v4 = __riscv_vadd_vx_i32m1_tu (v3, v2, x, 4);
+ __riscv_th_vsw_v_i32m1 (out, v4, 4);
+}
+
+/*
+** f2:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,ta,ma
+** th.vlw.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
+** th.vadd\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
+** th.vsw.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f2 (void * in, void *out, int32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vint32m1_t v = __riscv_th_vlw_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlw_v_i32m1_m (mask, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vx_i32m1 (v2, x, 4);
+ vint32m1_t v4 = __riscv_vadd_vx_i32m1_m (mask, v3, x, 4);
+ __riscv_th_vsw_v_i32m1 (out, v4, 4);
+}
+
+/*
+** f3:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,tu,mu
+** th.vlw\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlw.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vx\tv[0-9]+,\s*v[0-9]+,\s*[a-x0-9]+
+** th.vadd\.vx\tv[1-9][0-9]?,\s*v[0-9]+,\s*[a-x0-9]+,\s*v0.t
+** th.vsw.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f3 (void * in, void *out, int32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vint32m1_t v = __riscv_th_vlw_v_i32m1 (in, 4);
+ vint32m1_t v2 = __riscv_th_vlw_v_i32m1_tumu (mask, v, in, 4);
+ vint32m1_t v3 = __riscv_vadd_vx_i32m1 (v2, x, 4);
+ vint32m1_t v4 = __riscv_vadd_vx_i32m1_tumu (mask, v3, v2, x, 4);
+ __riscv_th_vsw_v_i32m1 (out, v4, 4);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlwu-vsw.c b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlwu-vsw.c
new file mode 100644
index 00000000000..b187cfc852b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/vlwu-vsw.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcxtheadvector -mabi=ilp32d -O3" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+#include "riscv_th_vector.h"
+
+/*
+** f1:
+** th.vsetivli\tzero,4,e32,m1,tu,ma
+** th.vlwu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlwu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vsw\.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f1 (void * in, void *out, uint32_t x)
+{
+ vuint32m1_t v = __riscv_th_vlwu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlwu_v_u32m1_tu (v, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_tu (v3, v2, -16, 4);
+ __riscv_th_vsw_v_u32m1 (out, v4, 4);
+}
+
+/*
+** f2:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,ta,ma
+** th.vlwu.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsw.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f2 (void * in, void *out, uint32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vuint32m1_t v = __riscv_th_vlwu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlwu_v_u32m1_m (mask, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_m (mask, v3, -16, 4);
+ __riscv_th_vsw_v_u32m1 (out, v4, 4);
+}
+
+/*
+** f3:
+** th.vsetvli\t[a-x0-9]+,zero,e8,mf4,ta,ma
+** th.vlm.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vsetivli\tzero,4,e32,m1,tu,mu
+** th.vlwu\.v\tv[0-9]+,0\([a-x0-9]+\)
+** th.vlwu.v\tv[0-9]+,0\([a-x0-9]+\),v0.t
+** th.vadd\.vi\tv[0-9]+,\s*v[0-9]+,\s*-16
+** th.vadd\.vi\tv[1-9][0-9]?,\s*v[0-9]+,\s*-16,\s*v0.t
+** th.vsw.v\tv[0-9]+,0\([a-x0-9]+\)
+** ret
+*/
+void f3 (void * in, void *out, uint32_t x)
+{
+ vbool32_t mask = *(vbool32_t*)in;
+ asm volatile ("":::"memory");
+ vuint32m1_t v = __riscv_th_vlwu_v_u32m1 (in, 4);
+ vuint32m1_t v2 = __riscv_th_vlwu_v_u32m1_tumu (mask, v, in, 4);
+ vuint32m1_t v3 = __riscv_vadd_vx_u32m1 (v2, -16, 4);
+ vuint32m1_t v4 = __riscv_vadd_vx_u32m1_tumu (mask, v3, v2, -16, 4);
+ __riscv_th_vsw_v_u32m1 (out, v4, 4);
+}

Additional information

@github-actions github-actions bot added linter-failure Lint failed apply-failure Patch failed to apply to baseline and tip of tree labels Jan 12, 2024
@ewlu ewlu closed this as completed Aug 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apply-failure Patch failed to apply to baseline and tip of tree linter-failure Lint failed
Projects
None yet
Development

No branches or pull requests

1 participant