RISC-V: Add vlm/vsm C/C++ API intrinsics support
authorJu-Zhe Zhong <juzhe.zhong@rivai.ai>
Thu, 19 Jan 2023 06:07:49 +0000 (14:07 +0800)
committerKito Cheng <kito.cheng@sifive.com>
Fri, 27 Jan 2023 12:44:37 +0000 (20:44 +0800)
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.

12 files changed:
gcc/config/riscv/riscv-vector-builtins-bases.cc
gcc/config/riscv/riscv-vector-builtins-bases.h
gcc/config/riscv/riscv-vector-builtins-functions.def
gcc/config/riscv/riscv-vector-builtins-shapes.cc
gcc/config/riscv/riscv-vector-builtins-types.def
gcc/config/riscv/riscv-vector-builtins.cc
gcc/config/riscv/vector.md
gcc/testsuite/g++.target/riscv/rvv/base/vsm-1.C [new file with mode: 0644]
gcc/testsuite/g++.target/riscv/rvv/rvv.exp [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/vlm_vsm-3.c [new file with mode: 0644]

index 5cd8e4d..cf6a060 100644 (file)
@@ -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
index 5044f57..7af462b 100644 (file)
@@ -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
index 2b4bd47..8bcaf2e 100644 (file)
@@ -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
index e796aa8..896704b 100644 (file)
@@ -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)
index 97d5713..a95fad0 100644 (file)
@@ -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
index e959ba3..9023930 100644 (file)
@@ -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)                         \
@@ -463,9 +485,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:
@@ -884,8 +916,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);
index 1dd81ae..8c60eb2 100644 (file)
 
 ;; 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)))
 
             (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
   [(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 (file)
index 0000000..60656cc
--- /dev/null
@@ -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 (file)
index 0000000..2495305
--- /dev/null
@@ -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 (file)
index 0000000..f2f4cc9
--- /dev/null
@@ -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 (file)
index 0000000..66e687f
--- /dev/null
@@ -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 (file)
index 0000000..58ca73c
--- /dev/null
@@ -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 } } */