RISC-V: Add vlm/vsm C/C++ API intrinsics support
Checks
Commit Message
From: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
gcc/ChangeLog:
* config/riscv/riscv-vector-builtins-bases.cc (BASE): Add vlm/vsm support.
* config/riscv/riscv-vector-builtins-bases.h: Ditto.
* config/riscv/riscv-vector-builtins-functions.def (vlm): New define.
(vsm): Ditto.
* config/riscv/riscv-vector-builtins-shapes.cc (struct loadstore_def): Add vlm/vsm support.
* config/riscv/riscv-vector-builtins-types.def (DEF_RVV_B_OPS): Ditto.
(vbool64_t): Ditto.
(vbool32_t): Ditto.
(vbool16_t): Ditto.
(vbool8_t): Ditto.
(vbool4_t): Ditto.
(vbool2_t): Ditto.
(vbool1_t): Ditto.
* config/riscv/riscv-vector-builtins.cc (DEF_RVV_B_OPS): Ditto.
(rvv_arg_type_info::get_tree_type): Ditto.
(function_expander::use_contiguous_load_insn): Ditto.
* config/riscv/vector.md (@pred_store<mode>): Ditto.
gcc/testsuite/ChangeLog:
* g++.target/riscv/rvv/base/vsm-1.C: New test.
* g++.target/riscv/rvv/rvv.exp: New test.
* gcc.target/riscv/rvv/base/vlm_vsm-1.c: New test.
* gcc.target/riscv/rvv/base/vlm_vsm-2.c: New test.
* gcc.target/riscv/rvv/base/vlm_vsm-3.c: New test.
---
.../riscv/riscv-vector-builtins-bases.cc | 6 +-
.../riscv/riscv-vector-builtins-bases.h | 2 +
.../riscv/riscv-vector-builtins-functions.def | 2 +
.../riscv/riscv-vector-builtins-shapes.cc | 3 +-
.../riscv/riscv-vector-builtins-types.def | 15 ++++
gcc/config/riscv/riscv-vector-builtins.cc | 43 ++++++++++-
gcc/config/riscv/vector.md | 23 +++++-
.../g++.target/riscv/rvv/base/vsm-1.C | 40 ++++++++++
gcc/testsuite/g++.target/riscv/rvv/rvv.exp | 44 +++++++++++
.../gcc.target/riscv/rvv/base/vlm_vsm-1.c | 75 +++++++++++++++++++
.../gcc.target/riscv/rvv/base/vlm_vsm-2.c | 75 +++++++++++++++++++
.../gcc.target/riscv/rvv/base/vlm_vsm-3.c | 75 +++++++++++++++++++
12 files changed, 395 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/vsm-1.C
create mode 100644 gcc/testsuite/g++.target/riscv/rvv/rvv.exp
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-3.c
Comments
committed, thanks!
On Thu, Jan 19, 2023 at 2:08 PM <juzhe.zhong@rivai.ai> wrote:
> From: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
>
> gcc/ChangeLog:
>
> * config/riscv/riscv-vector-builtins-bases.cc (BASE): Add vlm/vsm
> support.
> * config/riscv/riscv-vector-builtins-bases.h: Ditto.
> * config/riscv/riscv-vector-builtins-functions.def (vlm): New
> define.
> (vsm): Ditto.
> * config/riscv/riscv-vector-builtins-shapes.cc (struct
> loadstore_def): Add vlm/vsm support.
> * config/riscv/riscv-vector-builtins-types.def (DEF_RVV_B_OPS):
> Ditto.
> (vbool64_t): Ditto.
> (vbool32_t): Ditto.
> (vbool16_t): Ditto.
> (vbool8_t): Ditto.
> (vbool4_t): Ditto.
> (vbool2_t): Ditto.
> (vbool1_t): Ditto.
> * config/riscv/riscv-vector-builtins.cc (DEF_RVV_B_OPS): Ditto.
> (rvv_arg_type_info::get_tree_type): Ditto.
> (function_expander::use_contiguous_load_insn): Ditto.
> * config/riscv/vector.md (@pred_store<mode>): Ditto.
>
> gcc/testsuite/ChangeLog:
>
> * g++.target/riscv/rvv/base/vsm-1.C: New test.
> * g++.target/riscv/rvv/rvv.exp: New test.
> * gcc.target/riscv/rvv/base/vlm_vsm-1.c: New test.
> * gcc.target/riscv/rvv/base/vlm_vsm-2.c: New test.
> * gcc.target/riscv/rvv/base/vlm_vsm-3.c: New test.
>
> ---
> .../riscv/riscv-vector-builtins-bases.cc | 6 +-
> .../riscv/riscv-vector-builtins-bases.h | 2 +
> .../riscv/riscv-vector-builtins-functions.def | 2 +
> .../riscv/riscv-vector-builtins-shapes.cc | 3 +-
> .../riscv/riscv-vector-builtins-types.def | 15 ++++
> gcc/config/riscv/riscv-vector-builtins.cc | 43 ++++++++++-
> gcc/config/riscv/vector.md | 23 +++++-
> .../g++.target/riscv/rvv/base/vsm-1.C | 40 ++++++++++
> gcc/testsuite/g++.target/riscv/rvv/rvv.exp | 44 +++++++++++
> .../gcc.target/riscv/rvv/base/vlm_vsm-1.c | 75 +++++++++++++++++++
> .../gcc.target/riscv/rvv/base/vlm_vsm-2.c | 75 +++++++++++++++++++
> .../gcc.target/riscv/rvv/base/vlm_vsm-3.c | 75 +++++++++++++++++++
> 12 files changed, 395 insertions(+), 8 deletions(-)
> create mode 100644 gcc/testsuite/g++.target/riscv/rvv/base/vsm-1.C
> create mode 100644 gcc/testsuite/g++.target/riscv/rvv/rvv.exp
> create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-1.c
> create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-2.c
> create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-3.c
>
> diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> index af66b016b49..0da4797d272 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
> @@ -84,7 +84,7 @@ public:
> }
> };
>
> -/* Implements vle.v/vse.v codegen. */
> +/* Implements vle.v/vse.v/vlm.v/vsm.v codegen. */
> template <bool STORE_P>
> class loadstore : public function_base
> {
> @@ -116,6 +116,8 @@ static CONSTEXPR const vsetvl<false> vsetvl_obj;
> static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
> static CONSTEXPR const loadstore<false> vle_obj;
> static CONSTEXPR const loadstore<true> vse_obj;
> +static CONSTEXPR const loadstore<false> vlm_obj;
> +static CONSTEXPR const loadstore<true> vsm_obj;
>
> /* Declare the function base NAME, pointing it to an instance
> of class <NAME>_obj. */
> @@ -126,5 +128,7 @@ BASE (vsetvl)
> BASE (vsetvlmax)
> BASE (vle)
> BASE (vse)
> +BASE (vlm)
> +BASE (vsm)
>
> } // end namespace riscv_vector
> diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.h
> b/gcc/config/riscv/riscv-vector-builtins-bases.h
> index 79684bcb50d..28151a8d8d2 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-bases.h
> +++ b/gcc/config/riscv/riscv-vector-builtins-bases.h
> @@ -28,6 +28,8 @@ extern const function_base *const vsetvl;
> extern const function_base *const vsetvlmax;
> extern const function_base *const vle;
> extern const function_base *const vse;
> +extern const function_base *const vlm;
> +extern const function_base *const vsm;
> }
>
> } // end namespace riscv_vector
> diff --git a/gcc/config/riscv/riscv-vector-builtins-functions.def
> b/gcc/config/riscv/riscv-vector-builtins-functions.def
> index e5ebb7d829c..63aa8fe32c8 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-functions.def
> +++ b/gcc/config/riscv/riscv-vector-builtins-functions.def
> @@ -42,5 +42,7 @@ DEF_RVV_FUNCTION (vsetvlmax, vsetvlmax, none_preds,
> i_none_size_void_ops)
> /* 7. Vector Loads and Stores. */
> DEF_RVV_FUNCTION (vle, loadstore, full_preds, all_v_scalar_const_ptr_ops)
> DEF_RVV_FUNCTION (vse, loadstore, none_m_preds, all_v_scalar_ptr_ops)
> +DEF_RVV_FUNCTION (vlm, loadstore, none_preds, b_v_scalar_const_ptr_ops)
> +DEF_RVV_FUNCTION (vsm, loadstore, none_preds, b_v_scalar_ptr_ops)
>
> #undef DEF_RVV_FUNCTION
> diff --git a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> index 0332c031ce4..76cf14a8cc4 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins-shapes.cc
> @@ -116,7 +116,8 @@ struct loadstore_def : public build_base
> machine_mode mode = TYPE_MODE (type);
> int sew = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
> /* vop --> vop<sew>. */
> - b.append_sew (sew);
> + if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
> + b.append_sew (sew);
>
> /* vop<sew>_v --> vop<sew>_v_<type>. */
> if (!overloaded_p)
> diff --git a/gcc/config/riscv/riscv-vector-builtins-types.def
> b/gcc/config/riscv/riscv-vector-builtins-types.def
> index 6a867c99987..f86d8592c36 100644
> --- a/gcc/config/riscv/riscv-vector-builtins-types.def
> +++ b/gcc/config/riscv/riscv-vector-builtins-types.def
> @@ -36,6 +36,12 @@ along with GCC; see the file COPYING3. If not see
> #define DEF_RVV_F_OPS(TYPE, REQUIRE)
> #endif
>
> +/* Use "DEF_RVV_B_OPS" macro include all bool value which will be
> + iterated and registered as intrinsic functions. */
> +#ifndef DEF_RVV_B_OPS
> +#define DEF_RVV_B_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)
> @@ -92,6 +98,15 @@ DEF_RVV_F_OPS (vfloat64m2_t, RVV_REQUIRE_ELEN_FP_64)
> DEF_RVV_F_OPS (vfloat64m4_t, RVV_REQUIRE_ELEN_FP_64)
> DEF_RVV_F_OPS (vfloat64m8_t, RVV_REQUIRE_ELEN_FP_64)
>
> +DEF_RVV_B_OPS (vbool64_t, RVV_REQUIRE_ZVE64)
> +DEF_RVV_B_OPS (vbool32_t, 0)
> +DEF_RVV_B_OPS (vbool16_t, 0)
> +DEF_RVV_B_OPS (vbool8_t, 0)
> +DEF_RVV_B_OPS (vbool4_t, 0)
> +DEF_RVV_B_OPS (vbool2_t, 0)
> +DEF_RVV_B_OPS (vbool1_t, 0)
> +
> #undef DEF_RVV_I_OPS
> #undef DEF_RVV_U_OPS
> #undef DEF_RVV_F_OPS
> +#undef DEF_RVV_B_OPS
> diff --git a/gcc/config/riscv/riscv-vector-builtins.cc
> b/gcc/config/riscv/riscv-vector-builtins.cc
> index 47e01b647f8..f95fe0d58d5 100644
> --- a/gcc/config/riscv/riscv-vector-builtins.cc
> +++ b/gcc/config/riscv/riscv-vector-builtins.cc
> @@ -141,6 +141,12 @@ static const rvv_type_info all_ops[] = {
> #include "riscv-vector-builtins-types.def"
> {NUM_VECTOR_TYPES, 0}};
>
> +/* A list of all bool will be registered for intrinsic functions. */
> +static const rvv_type_info b_ops[] = {
> +#define DEF_RVV_B_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);
>
> @@ -205,6 +211,22 @@ static CONSTEXPR const rvv_op_info
> all_v_scalar_ptr_ops
> rvv_arg_type_info (RVV_BASE_void), /* Return type */
> scalar_ptr_args /* Args */};
>
> +/* A static operand information for vector_type func (const scalar_type *)
> + * function registration. */
> +static CONSTEXPR const rvv_op_info b_v_scalar_const_ptr_ops
> + = {b_ops, /* Types */
> + OP_TYPE_v, /* Suffix */
> + rvv_arg_type_info (RVV_BASE_vector), /* Return type */
> + scalar_const_ptr_args /* Args */};
> +
> +/* A static operand information for void func (scalar_type *, vector_type)
> + * function registration. */
> +static CONSTEXPR const rvv_op_info b_v_scalar_ptr_ops
> + = {b_ops, /* Types */
> + OP_TYPE_v, /* Suffix */
> + rvv_arg_type_info (RVV_BASE_void), /* Return type */
> + scalar_ptr_args /* Args */};
> +
> /* A list of all RVV intrinsic functions. */
> static function_group_info function_groups[] = {
> #define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO)
> \
> @@ -462,9 +484,19 @@ rvv_arg_type_info::get_tree_type (vector_type_index
> type_idx) const
> case RVV_BASE_vector_ptr:
> return builtin_types[type_idx].vector_ptr;
> case RVV_BASE_scalar_ptr:
> - return builtin_types[type_idx].scalar_ptr;
> + /* According to the latest rvv-intrinsic-doc, it defines vsm.v
> intrinsic:
> + __riscv_vsm (uint8_t *base, vbool1_t value, size_t vl). */
> + if (type_idx >= VECTOR_TYPE_vbool64_t && type_idx <=
> VECTOR_TYPE_vbool1_t)
> + return builtin_types[VECTOR_TYPE_vuint8mf8_t].scalar_ptr;
> + else
> + return builtin_types[type_idx].scalar_ptr;
> case RVV_BASE_scalar_const_ptr:
> - return builtin_types[type_idx].scalar_const_ptr;
> + /* According to the latest rvv-intrinsic-doc, it defines vlm.v
> intrinsic:
> + __riscv_vlm_v_b1 (const uint8_t *base, size_t vl). */
> + if (type_idx >= VECTOR_TYPE_vbool64_t && type_idx <=
> VECTOR_TYPE_vbool1_t)
> + return builtin_types[VECTOR_TYPE_vuint8mf8_t].scalar_const_ptr;
> + else
> + return builtin_types[type_idx].scalar_const_ptr;
> case RVV_BASE_void:
> return void_type_node;
> case RVV_BASE_size:
> @@ -883,8 +915,11 @@ function_expander::use_contiguous_load_insn
> (insn_code icode)
> for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++)
> add_input_operand (argno);
>
> - add_input_operand (Pmode, get_tail_policy_for_pred (pred));
> - add_input_operand (Pmode, get_mask_policy_for_pred (pred));
> + if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
> + {
> + add_input_operand (Pmode, get_tail_policy_for_pred (pred));
> + add_input_operand (Pmode, get_mask_policy_for_pred (pred));
> + }
> add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
>
> return generate_insn (icode);
> diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
> index 37cf4d6bcbf..48414e200cf 100644
> --- a/gcc/config/riscv/vector.md
> +++ b/gcc/config/riscv/vector.md
> @@ -198,7 +198,7 @@
>
> ;; The index of operand[] to get the merge op.
> (define_attr "merge_op_idx" ""
> - (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vstm,vlds,vmalu")
> + (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu")
> (const_int 2)]
> (const_int INVALID_ATTRIBUTE)))
>
> @@ -694,7 +694,7 @@
> (reg:SI VL_REGNUM)
> (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
> (match_operand:VB 3 "vector_move_operand" " m, vr, vr,
> Wc0, Wc1")
> - (match_operand:VB 2 "vector_merge_operand" " vu, vu0, vu,
> vu, vu")))]
> + (match_operand:VB 2 "vector_merge_operand" " vu, vu, vu,
> vu, vu")))]
> "TARGET_VECTOR"
> "@
> vlm.v\t%0,%3
> @@ -709,6 +709,25 @@
> [(set_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
> (set_attr "mode" "<MODE>")])
>
> +;; Dedicated pattern for vsm.v instruction since we can't reuse pred_mov
> pattern to include
> +;; memory operand as input which will produce inferior codegen.
> +(define_insn "@pred_store<mode>"
> + [(set (match_operand:VB 0 "memory_operand" "+m")
> + (if_then_else:VB
> + (unspec:VB
> + [(match_operand:VB 1 "vector_mask_operand" "Wc1")
> + (match_operand 3 "vector_length_operand" " rK")
> + (reg:SI VL_REGNUM)
> + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
> + (match_operand:VB 2 "register_operand" " vr")
> + (match_dup 0)))]
> + "TARGET_VECTOR"
> + "vsm.v\t%2,%0"
> + [(set_attr "type" "vstm")
> + (set_attr "mode" "<MODE>")
> + (set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
> + (set_attr "vl_op_idx" "3")])
> +
> ;;
> -------------------------------------------------------------------------------
> ;; ---- Predicated Broadcast
> ;;
> -------------------------------------------------------------------------------
> diff --git a/gcc/testsuite/g++.target/riscv/rvv/base/vsm-1.C
> b/gcc/testsuite/g++.target/riscv/rvv/base/vsm-1.C
> new file mode 100644
> index 00000000000..60656cc353f
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/riscv/rvv/base/vsm-1.C
> @@ -0,0 +1,40 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns
> -fno-schedule-insns2" } */
> +
> +#include "riscv_vector.h"
> +
> +void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
> + __riscv_vsm(base, value, vl);
> +}
> +
> +void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
> + __riscv_vsm(base, value, vl);
> +}
> +
> +void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
> + __riscv_vsm(base, value, vl);
> +}
> +
> +void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
> + __riscv_vsm(base, value, vl);
> +}
> +
> +void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl)
> {
> + __riscv_vsm(base, value, vl);
> +}
> +
> +void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl)
> {
> + __riscv_vsm(base, value, vl);
> +}
> +
> +void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl)
> {
> + __riscv_vsm(base, value, vl);
> +}
> +
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> diff --git a/gcc/testsuite/g++.target/riscv/rvv/rvv.exp
> b/gcc/testsuite/g++.target/riscv/rvv/rvv.exp
> new file mode 100644
> index 00000000000..249530580d7
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/riscv/rvv/rvv.exp
> @@ -0,0 +1,44 @@
> +# Copyright (C) 2023-2023 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3. If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +# GCC testsuite that uses the `dg.exp' driver.
> +
> +# Test the front-end for C++.
> +# We don't need to test back-end code-gen in RV32 system for C++
> +# Because it is already tested in C.
> +# Exit immediately if this isn't a RISC-V target.
> +if ![istarget riscv*-*-*] then {
> + return
> +}
> +
> +# Load support procs.
> +load_lib g++-dg.exp
> +
> +set gcc_march "rv64gcv_zfh"
> +if [istarget riscv32-*-*] then {
> + set gcc_march "rv32gcv_zfh"
> +}
> +
> +# Initialize `dg'.
> +dg-init
> +
> +# Main loop.
> +set CFLAGS "-march=$gcc_march -O3"
> +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/base/*.C]] \
> + "" $CFLAGS
> +
> +# All done.
> +dg-finish
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-1.c
> b/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-1.c
> new file mode 100644
> index 00000000000..f2f4cc97e1b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-1.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns
> -fno-schedule-insns2" } */
> +
> +#include "riscv_vector.h"
> +
> +vbool1_t test___riscv_vlm_v_b1_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b1(base, vl);
> +}
> +
> +void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
> + __riscv_vsm_v_b1(base, value, vl);
> +}
> +
> +vbool2_t test___riscv_vlm_v_b2_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b2(base, vl);
> +}
> +
> +void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
> + __riscv_vsm_v_b2(base, value, vl);
> +}
> +
> +vbool4_t test___riscv_vlm_v_b4_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b4(base, vl);
> +}
> +
> +void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
> + __riscv_vsm_v_b4(base, value, vl);
> +}
> +
> +vbool8_t test___riscv_vlm_v_b8_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b8(base, vl);
> +}
> +
> +void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
> + __riscv_vsm_v_b8(base, value, vl);
> +}
> +
> +vbool16_t test___riscv_vlm_v_b16_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b16(base, vl);
> +}
> +
> +void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl)
> {
> + __riscv_vsm_v_b16(base, value, vl);
> +}
> +
> +vbool32_t test___riscv_vlm_v_b32_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b32(base, vl);
> +}
> +
> +void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl)
> {
> + __riscv_vsm_v_b32(base, value, vl);
> +}
> +
> +vbool64_t test___riscv_vlm_v_b64_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b64(base, vl);
> +}
> +
> +void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl)
> {
> + __riscv_vsm_v_b64(base, value, vl);
> +}
> +
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-2.c
> b/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-2.c
> new file mode 100644
> index 00000000000..66e687fd8bf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-2.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns
> -fno-schedule-insns2" } */
> +
> +#include "riscv_vector.h"
> +
> +vbool1_t test___riscv_vlm_v_b1_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b1(base, 31);
> +}
> +
> +void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
> + __riscv_vsm_v_b1(base, value, 31);
> +}
> +
> +vbool2_t test___riscv_vlm_v_b2_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b2(base, 31);
> +}
> +
> +void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
> + __riscv_vsm_v_b2(base, value, 31);
> +}
> +
> +vbool4_t test___riscv_vlm_v_b4_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b4(base, 31);
> +}
> +
> +void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
> + __riscv_vsm_v_b4(base, value, 31);
> +}
> +
> +vbool8_t test___riscv_vlm_v_b8_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b8(base, 31);
> +}
> +
> +void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
> + __riscv_vsm_v_b8(base, value, 31);
> +}
> +
> +vbool16_t test___riscv_vlm_v_b16_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b16(base, 31);
> +}
> +
> +void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl)
> {
> + __riscv_vsm_v_b16(base, value, 31);
> +}
> +
> +vbool32_t test___riscv_vlm_v_b32_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b32(base, 31);
> +}
> +
> +void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl)
> {
> + __riscv_vsm_v_b32(base, value, 31);
> +}
> +
> +vbool64_t test___riscv_vlm_v_b64_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b64(base, 31);
> +}
> +
> +void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl)
> {
> + __riscv_vsm_v_b64(base, value, 31);
> +}
> +
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetivli\s+zero,\s*31,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-3.c
> b/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-3.c
> new file mode 100644
> index 00000000000..58ca73c10a2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-3.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns
> -fno-schedule-insns2" } */
> +
> +#include "riscv_vector.h"
> +
> +vbool1_t test___riscv_vlm_v_b1_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b1(base, 32);
> +}
> +
> +void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
> + __riscv_vsm_v_b1(base, value, 32);
> +}
> +
> +vbool2_t test___riscv_vlm_v_b2_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b2(base, 32);
> +}
> +
> +void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
> + __riscv_vsm_v_b2(base, value, 32);
> +}
> +
> +vbool4_t test___riscv_vlm_v_b4_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b4(base, 32);
> +}
> +
> +void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
> + __riscv_vsm_v_b4(base, value, 32);
> +}
> +
> +vbool8_t test___riscv_vlm_v_b8_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b8(base, 32);
> +}
> +
> +void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
> + __riscv_vsm_v_b8(base, value, 32);
> +}
> +
> +vbool16_t test___riscv_vlm_v_b16_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b16(base, 32);
> +}
> +
> +void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl)
> {
> + __riscv_vsm_v_b16(base, value, 32);
> +}
> +
> +vbool32_t test___riscv_vlm_v_b32_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b32(base, 32);
> +}
> +
> +void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl)
> {
> + __riscv_vsm_v_b32(base, value, 32);
> +}
> +
> +vbool64_t test___riscv_vlm_v_b64_vl(const uint8_t *base, size_t vl) {
> + return __riscv_vlm_v_b64(base, 32);
> +}
> +
> +void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl)
> {
> + __riscv_vsm_v_b64(base, value, 32);
> +}
> +
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> +/* { dg-final { scan-assembler-times
> {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)}
> 1 } } */
> --
> 2.36.3
>
>
@@ -84,7 +84,7 @@ public:
}
};
-/* Implements vle.v/vse.v codegen. */
+/* Implements vle.v/vse.v/vlm.v/vsm.v codegen. */
template <bool STORE_P>
class loadstore : public function_base
{
@@ -116,6 +116,8 @@ static CONSTEXPR const vsetvl<false> vsetvl_obj;
static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
static CONSTEXPR const loadstore<false> vle_obj;
static CONSTEXPR const loadstore<true> vse_obj;
+static CONSTEXPR const loadstore<false> vlm_obj;
+static CONSTEXPR const loadstore<true> vsm_obj;
/* Declare the function base NAME, pointing it to an instance
of class <NAME>_obj. */
@@ -126,5 +128,7 @@ BASE (vsetvl)
BASE (vsetvlmax)
BASE (vle)
BASE (vse)
+BASE (vlm)
+BASE (vsm)
} // end namespace riscv_vector
@@ -28,6 +28,8 @@ extern const function_base *const vsetvl;
extern const function_base *const vsetvlmax;
extern const function_base *const vle;
extern const function_base *const vse;
+extern const function_base *const vlm;
+extern const function_base *const vsm;
}
} // end namespace riscv_vector
@@ -42,5 +42,7 @@ DEF_RVV_FUNCTION (vsetvlmax, vsetvlmax, none_preds, i_none_size_void_ops)
/* 7. Vector Loads and Stores. */
DEF_RVV_FUNCTION (vle, loadstore, full_preds, all_v_scalar_const_ptr_ops)
DEF_RVV_FUNCTION (vse, loadstore, none_m_preds, all_v_scalar_ptr_ops)
+DEF_RVV_FUNCTION (vlm, loadstore, none_preds, b_v_scalar_const_ptr_ops)
+DEF_RVV_FUNCTION (vsm, loadstore, none_preds, b_v_scalar_ptr_ops)
#undef DEF_RVV_FUNCTION
@@ -116,7 +116,8 @@ struct loadstore_def : public build_base
machine_mode mode = TYPE_MODE (type);
int sew = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
/* vop --> vop<sew>. */
- b.append_sew (sew);
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
+ b.append_sew (sew);
/* vop<sew>_v --> vop<sew>_v_<type>. */
if (!overloaded_p)
@@ -36,6 +36,12 @@ along with GCC; see the file COPYING3. If not see
#define DEF_RVV_F_OPS(TYPE, REQUIRE)
#endif
+/* Use "DEF_RVV_B_OPS" macro include all bool value which will be
+ iterated and registered as intrinsic functions. */
+#ifndef DEF_RVV_B_OPS
+#define DEF_RVV_B_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)
@@ -92,6 +98,15 @@ DEF_RVV_F_OPS (vfloat64m2_t, RVV_REQUIRE_ELEN_FP_64)
DEF_RVV_F_OPS (vfloat64m4_t, RVV_REQUIRE_ELEN_FP_64)
DEF_RVV_F_OPS (vfloat64m8_t, RVV_REQUIRE_ELEN_FP_64)
+DEF_RVV_B_OPS (vbool64_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_B_OPS (vbool32_t, 0)
+DEF_RVV_B_OPS (vbool16_t, 0)
+DEF_RVV_B_OPS (vbool8_t, 0)
+DEF_RVV_B_OPS (vbool4_t, 0)
+DEF_RVV_B_OPS (vbool2_t, 0)
+DEF_RVV_B_OPS (vbool1_t, 0)
+
#undef DEF_RVV_I_OPS
#undef DEF_RVV_U_OPS
#undef DEF_RVV_F_OPS
+#undef DEF_RVV_B_OPS
@@ -141,6 +141,12 @@ static const rvv_type_info all_ops[] = {
#include "riscv-vector-builtins-types.def"
{NUM_VECTOR_TYPES, 0}};
+/* A list of all bool will be registered for intrinsic functions. */
+static const rvv_type_info b_ops[] = {
+#define DEF_RVV_B_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);
@@ -205,6 +211,22 @@ static CONSTEXPR const rvv_op_info all_v_scalar_ptr_ops
rvv_arg_type_info (RVV_BASE_void), /* Return type */
scalar_ptr_args /* Args */};
+/* A static operand information for vector_type func (const scalar_type *)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_v_scalar_const_ptr_ops
+ = {b_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_vector), /* Return type */
+ scalar_const_ptr_args /* Args */};
+
+/* A static operand information for void func (scalar_type *, vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info b_v_scalar_ptr_ops
+ = {b_ops, /* Types */
+ OP_TYPE_v, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_void), /* Return type */
+ scalar_ptr_args /* Args */};
+
/* A list of all RVV intrinsic functions. */
static function_group_info function_groups[] = {
#define DEF_RVV_FUNCTION(NAME, SHAPE, PREDS, OPS_INFO) \
@@ -462,9 +484,19 @@ rvv_arg_type_info::get_tree_type (vector_type_index type_idx) const
case RVV_BASE_vector_ptr:
return builtin_types[type_idx].vector_ptr;
case RVV_BASE_scalar_ptr:
- return builtin_types[type_idx].scalar_ptr;
+ /* According to the latest rvv-intrinsic-doc, it defines vsm.v intrinsic:
+ __riscv_vsm (uint8_t *base, vbool1_t value, size_t vl). */
+ if (type_idx >= VECTOR_TYPE_vbool64_t && type_idx <= VECTOR_TYPE_vbool1_t)
+ return builtin_types[VECTOR_TYPE_vuint8mf8_t].scalar_ptr;
+ else
+ return builtin_types[type_idx].scalar_ptr;
case RVV_BASE_scalar_const_ptr:
- return builtin_types[type_idx].scalar_const_ptr;
+ /* According to the latest rvv-intrinsic-doc, it defines vlm.v intrinsic:
+ __riscv_vlm_v_b1 (const uint8_t *base, size_t vl). */
+ if (type_idx >= VECTOR_TYPE_vbool64_t && type_idx <= VECTOR_TYPE_vbool1_t)
+ return builtin_types[VECTOR_TYPE_vuint8mf8_t].scalar_const_ptr;
+ else
+ return builtin_types[type_idx].scalar_const_ptr;
case RVV_BASE_void:
return void_type_node;
case RVV_BASE_size:
@@ -883,8 +915,11 @@ function_expander::use_contiguous_load_insn (insn_code icode)
for (int argno = arg_offset; argno < call_expr_nargs (exp); argno++)
add_input_operand (argno);
- add_input_operand (Pmode, get_tail_policy_for_pred (pred));
- add_input_operand (Pmode, get_mask_policy_for_pred (pred));
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
+ {
+ add_input_operand (Pmode, get_tail_policy_for_pred (pred));
+ add_input_operand (Pmode, get_mask_policy_for_pred (pred));
+ }
add_input_operand (Pmode, get_avl_type_rtx (avl_type::NONVLMAX));
return generate_insn (icode);
@@ -198,7 +198,7 @@
;; The index of operand[] to get the merge op.
(define_attr "merge_op_idx" ""
- (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vstm,vlds,vmalu")
+ (cond [(eq_attr "type" "vlde,vimov,vfmov,vldm,vlds,vmalu")
(const_int 2)]
(const_int INVALID_ATTRIBUTE)))
@@ -694,7 +694,7 @@
(reg:SI VL_REGNUM)
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
(match_operand:VB 3 "vector_move_operand" " m, vr, vr, Wc0, Wc1")
- (match_operand:VB 2 "vector_merge_operand" " vu, vu0, vu, vu, vu")))]
+ (match_operand:VB 2 "vector_merge_operand" " vu, vu, vu, vu, vu")))]
"TARGET_VECTOR"
"@
vlm.v\t%0,%3
@@ -709,6 +709,25 @@
[(set_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
(set_attr "mode" "<MODE>")])
+;; Dedicated pattern for vsm.v instruction since we can't reuse pred_mov pattern to include
+;; memory operand as input which will produce inferior codegen.
+(define_insn "@pred_store<mode>"
+ [(set (match_operand:VB 0 "memory_operand" "+m")
+ (if_then_else:VB
+ (unspec:VB
+ [(match_operand:VB 1 "vector_mask_operand" "Wc1")
+ (match_operand 3 "vector_length_operand" " rK")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operand:VB 2 "register_operand" " vr")
+ (match_dup 0)))]
+ "TARGET_VECTOR"
+ "vsm.v\t%2,%0"
+ [(set_attr "type" "vstm")
+ (set_attr "mode" "<MODE>")
+ (set (attr "avl_type") (symbol_ref "riscv_vector::NONVLMAX"))
+ (set_attr "vl_op_idx" "3")])
+
;; -------------------------------------------------------------------------------
;; ---- Predicated Broadcast
;; -------------------------------------------------------------------------------
new file mode 100644
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include "riscv_vector.h"
+
+void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
+ __riscv_vsm(base, value, vl);
+}
+
+void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
+ __riscv_vsm(base, value, vl);
+}
+
+void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
+ __riscv_vsm(base, value, vl);
+}
+
+void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
+ __riscv_vsm(base, value, vl);
+}
+
+void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl) {
+ __riscv_vsm(base, value, vl);
+}
+
+void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl) {
+ __riscv_vsm(base, value, vl);
+}
+
+void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl) {
+ __riscv_vsm(base, value, vl);
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
new file mode 100644
@@ -0,0 +1,44 @@
+# Copyright (C) 2023-2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Test the front-end for C++.
+# We don't need to test back-end code-gen in RV32 system for C++
+# Because it is already tested in C.
+# Exit immediately if this isn't a RISC-V target.
+if ![istarget riscv*-*-*] then {
+ return
+}
+
+# Load support procs.
+load_lib g++-dg.exp
+
+set gcc_march "rv64gcv_zfh"
+if [istarget riscv32-*-*] then {
+ set gcc_march "rv32gcv_zfh"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+set CFLAGS "-march=$gcc_march -O3"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/base/*.C]] \
+ "" $CFLAGS
+
+# All done.
+dg-finish
new file mode 100644
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include "riscv_vector.h"
+
+vbool1_t test___riscv_vlm_v_b1_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b1(base, vl);
+}
+
+void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
+ __riscv_vsm_v_b1(base, value, vl);
+}
+
+vbool2_t test___riscv_vlm_v_b2_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b2(base, vl);
+}
+
+void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
+ __riscv_vsm_v_b2(base, value, vl);
+}
+
+vbool4_t test___riscv_vlm_v_b4_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b4(base, vl);
+}
+
+void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
+ __riscv_vsm_v_b4(base, value, vl);
+}
+
+vbool8_t test___riscv_vlm_v_b8_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b8(base, vl);
+}
+
+void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
+ __riscv_vsm_v_b8(base, value, vl);
+}
+
+vbool16_t test___riscv_vlm_v_b16_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b16(base, vl);
+}
+
+void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl) {
+ __riscv_vsm_v_b16(base, value, vl);
+}
+
+vbool32_t test___riscv_vlm_v_b32_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b32(base, vl);
+}
+
+void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl) {
+ __riscv_vsm_v_b32(base, value, vl);
+}
+
+vbool64_t test___riscv_vlm_v_b64_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b64(base, vl);
+}
+
+void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl) {
+ __riscv_vsm_v_b64(base, value, vl);
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
new file mode 100644
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include "riscv_vector.h"
+
+vbool1_t test___riscv_vlm_v_b1_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b1(base, 31);
+}
+
+void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
+ __riscv_vsm_v_b1(base, value, 31);
+}
+
+vbool2_t test___riscv_vlm_v_b2_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b2(base, 31);
+}
+
+void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
+ __riscv_vsm_v_b2(base, value, 31);
+}
+
+vbool4_t test___riscv_vlm_v_b4_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b4(base, 31);
+}
+
+void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
+ __riscv_vsm_v_b4(base, value, 31);
+}
+
+vbool8_t test___riscv_vlm_v_b8_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b8(base, 31);
+}
+
+void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
+ __riscv_vsm_v_b8(base, value, 31);
+}
+
+vbool16_t test___riscv_vlm_v_b16_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b16(base, 31);
+}
+
+void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl) {
+ __riscv_vsm_v_b16(base, value, 31);
+}
+
+vbool32_t test___riscv_vlm_v_b32_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b32(base, 31);
+}
+
+void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl) {
+ __riscv_vsm_v_b32(base, value, 31);
+}
+
+vbool64_t test___riscv_vlm_v_b64_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b64(base, 31);
+}
+
+void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl) {
+ __riscv_vsm_v_b64(base, value, 31);
+}
+
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*31,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
new file mode 100644
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+
+#include "riscv_vector.h"
+
+vbool1_t test___riscv_vlm_v_b1_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b1(base, 32);
+}
+
+void test___riscv_vsm_v_b1_vl(uint8_t *base, vbool1_t value, size_t vl) {
+ __riscv_vsm_v_b1(base, value, 32);
+}
+
+vbool2_t test___riscv_vlm_v_b2_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b2(base, 32);
+}
+
+void test___riscv_vsm_v_b2_vl(uint8_t *base, vbool2_t value, size_t vl) {
+ __riscv_vsm_v_b2(base, value, 32);
+}
+
+vbool4_t test___riscv_vlm_v_b4_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b4(base, 32);
+}
+
+void test___riscv_vsm_v_b4_vl(uint8_t *base, vbool4_t value, size_t vl) {
+ __riscv_vsm_v_b4(base, value, 32);
+}
+
+vbool8_t test___riscv_vlm_v_b8_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b8(base, 32);
+}
+
+void test___riscv_vsm_v_b8_vl(uint8_t *base, vbool8_t value, size_t vl) {
+ __riscv_vsm_v_b8(base, value, 32);
+}
+
+vbool16_t test___riscv_vlm_v_b16_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b16(base, 32);
+}
+
+void test___riscv_vsm_v_b16_vl(uint8_t *base, vbool16_t value, size_t vl) {
+ __riscv_vsm_v_b16(base, value, 32);
+}
+
+vbool32_t test___riscv_vlm_v_b32_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b32(base, 32);
+}
+
+void test___riscv_vsm_v_b32_vl(uint8_t *base, vbool32_t value, size_t vl) {
+ __riscv_vsm_v_b32(base, value, 32);
+}
+
+vbool64_t test___riscv_vlm_v_b64_vl(const uint8_t *base, size_t vl) {
+ return __riscv_vlm_v_b64(base, 32);
+}
+
+void test___riscv_vsm_v_b64_vl(uint8_t *base, vbool64_t value, size_t vl) {
+ __riscv_vsm_v_b64(base, value, 32);
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf2,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf4,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vlm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+zero,\s*[a-x0-9]+,\s*e8,\s*mf8,\s*t[au],\s*m[au]\s+vsm\.v\s+v[0-9]+,\s*0\([a-x0-9]+\)} 1 } } */