public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
@ 2024-03-06  6:38 pan2.li
  2024-03-06  6:46 ` juzhe.zhong
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: pan2.li @ 2024-03-06  6:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: juzhe.zhong, kito.cheng, yanzhang.wang, Pan Li

From: Pan Li <pan2.li@intel.com>

This patch would like to introduce one new gcc attribute for RVV.
This attribute is used to define fixed-length variants of one
existing sizeless RVV types.

This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
one args should be the integer constant and its' value is terminated
by the LMUL and the vector register bits in zvl*b.  For example:

typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));

The above type define is invalid when -march=rv64gc_zve64d_zvl64b
(aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
-march=rv64gcv_zvl128b similar to below.

"error: invalid RVV vector size '128', expected size is '256' based on
LMUL of type and '-mrvv-vector-bits=zvl'"

For the vint*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -

For the vfloat*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, -

For the vbool*_t types only below operations are allowed except
the CMP and ALU. The CMP and ALU operations on vbool*_t is not
well defined currently.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.

For the vint*x*m*_t tuple types are not suppored in this patch
which is compatible with clang.

This patch passed the below testsuites.
* The riscv fully regression tests.

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
	New static func to take care of the RVV types decorated by
	the attributes.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv.cc                     |  88 +++++++++++++-
 .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
 .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
 14 files changed, 600 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 56cd8d2c23f..fdbaf1633ac 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -535,6 +535,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
 static bool riscv_avoid_shrink_wrapping_separate ();
 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
+static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
+						    bool *);
 
 /* Defining target-specific uses of __attribute__.  */
 static const attribute_spec riscv_gnu_attributes[] =
@@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
     standard vector calling convention variant. Syntax:
     __attribute__((riscv_vector_cc)). */
-  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_gnu_attribute_table  =
@@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
      standard vector calling convention variant. Syntax:
      [[riscv::vector_cc]]. */
-  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_nongnu_attribute_table =
@@ -5561,6 +5583,68 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
   return NULL_TREE;
 }
 
+static tree
+riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
+					ATTRIBUTE_UNUSED int flags,
+					bool *no_add_attrs)
+{
+  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
+    return NULL_TREE;
+
+  *no_add_attrs = true;
+
+  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
+    {
+      error (
+	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
+	"riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  tree type = *node;
+
+  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
+    {
+      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
+      return NULL_TREE;
+    }
+
+  tree size = TREE_VALUE (args);
+
+  if (TREE_CODE (size) != INTEGER_CST)
+    {
+      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
+  machine_mode mode = TYPE_MODE (type);
+  unsigned HOST_WIDE_INT type_mode_bits
+    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
+
+  if (args_in_bits != type_mode_bits)
+    {
+      error ("invalid RVV vector size %qd, "
+	     "expected size is %qd based on LMUL of type and %qs",
+	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
+      return NULL_TREE;
+    }
+
+  type = build_distinct_type_copy (type);
+  TYPE_ATTRIBUTES (type)
+    = remove_attribute ("RVV sizeless type",
+			copy_list (TYPE_ATTRIBUTES (type)));
+
+  /* The operations like alu/cmp on vbool*_t is not well defined,
+     continue to treat vbool*_t as indivisible.  */
+  if (!VECTOR_BOOLEAN_TYPE_P (type))
+    TYPE_INDIVISIBLE_P (type) = 0;
+
+  *node = type;
+
+  return NULL_TREE;
+}
+
 /* Return true if function TYPE is an interrupt function.  */
 static bool
 riscv_interrupt_type_p (tree type)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
new file mode 100644
index 00000000000..8b08ba28130
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
new file mode 100644
index 00000000000..0ff48a29f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
new file mode 100644
index 00000000000..726c56b4a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
new file mode 100644
index 00000000000..5c2346dff3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
new file mode 100644
index 00000000000..6b841d7b1d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
new file mode 100644
index 00000000000..e1b0664eacb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
new file mode 100644
index 00000000000..eef15654110
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
new file mode 100644
index 00000000000..6b4f19cd9f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
new file mode 100644
index 00000000000..bc346917fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
new file mode 100644
index 00000000000..611a4bb88ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
new file mode 100644
index 00000000000..bb8d1da72b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
new file mode 100644
index 00000000000..701f833b41b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
new file mode 100644
index 00000000000..a7d68f2c36b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
@@ -0,0 +1,108 @@
+#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+
+#include "riscv_vector.h"
+#include "../autovec/vls/def.h"
+
+#define DEF_FIXED_TYPE(T, N)                                                   \
+  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
+
+#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
+  fixed_##T global_fixed_##T##_##N##_bits_var;
+
+#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
+  struct fixed_##T##_##N##_bits_struct                                         \
+  {                                                                            \
+    fixed_##T a, b[2];                                                         \
+  };
+
+#define DEF_FIXED_UNION_TYPE(T, N)                                             \
+  union fixed_##T##_##N##_bits_union                                           \
+  {                                                                            \
+    fixed_##T a, b[3];                                                         \
+  };
+
+#define TEST_FIXED_TYPE_SIZE(T, N)                                             \
+  void test_fixed_##T##_##N##_bits_size ()                                     \
+  {                                                                            \
+    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
+		    "Fixed RVV register types should be equal.");              \
+  }
+
+#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                    \
+  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
+  {                                                                            \
+    return (NEW_TYPE) a;                                                       \
+  }
+
+#define TEST_FIXED_BINARY(T, N, OP, NAME)                                      \
+  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
+						       fixed_##T b)            \
+  {                                                                            \
+    return a OP b;                                                             \
+  }
+
+#define TEST_FIXED_UNARY(T, N, OP, NAME)                                       \
+  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
+  {                                                                            \
+    return OP a;                                                               \
+  }
+
+#define TEST_FIXED_TYPE_CMP(T, N)                                              \
+  TEST_FIXED_BINARY(T, N, ==, eq)                                              \
+  TEST_FIXED_BINARY(T, N, !=, ne)                                              \
+  TEST_FIXED_BINARY(T, N, >,  gt)                                              \
+  TEST_FIXED_BINARY(T, N, <,  lt)                                              \
+  TEST_FIXED_BINARY(T, N, >=, ge)                                              \
+  TEST_FIXED_BINARY(T, N, <=, le)
+
+#define TEST_FIXED_TYPE_INT_ALU(T, N)                                          \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_BINARY(T, N, %,  mod)                                             \
+  TEST_FIXED_BINARY(T, N, &,  and)                                             \
+  TEST_FIXED_BINARY(T, N, |,  ior)                                             \
+  TEST_FIXED_BINARY(T, N, ^,  xor)                                             \
+  TEST_FIXED_BINARY(T, N, >>, rsh)                                             \
+  TEST_FIXED_BINARY(T, N, <<, lsh)                                             \
+  TEST_FIXED_UNARY(T, N, ~, not)                                               \
+  TEST_FIXED_UNARY(T, N, -, neg)
+
+#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                        \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_UNARY(T, N, -,  neg)
+
+#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_INT_ALU (T, N)                                               \
+
+#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                             \
+
+#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
+
+#endif
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-06  6:38 [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV pan2.li
@ 2024-03-06  6:46 ` juzhe.zhong
  2024-03-06  7:27 ` [PATCH v2] " pan2.li
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: juzhe.zhong @ 2024-03-06  6:46 UTC (permalink / raw)
  To: pan2.li, gcc-patches
  Cc: kito.cheng, yanzhang.wang, pan2.li, Robin Dapp, vineetg, palmer

[-- Attachment #1: Type: text/plain, Size: 39135 bytes --]

Thanks for support it.
I leave this patch review to kito who is much more familiar with it than me.

CCing more folks who may be interested at this stuff.



juzhe.zhong@rivai.ai
 
From: pan2.li
Date: 2024-03-06 14:38
To: gcc-patches
CC: juzhe.zhong; kito.cheng; yanzhang.wang; Pan Li
Subject: [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
From: Pan Li <pan2.li@intel.com>
 
This patch would like to introduce one new gcc attribute for RVV.
This attribute is used to define fixed-length variants of one
existing sizeless RVV types.
 
This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
one args should be the integer constant and its' value is terminated
by the LMUL and the vector register bits in zvl*b.  For example:
 
typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
 
The above type define is invalid when -march=rv64gc_zve64d_zvl64b
(aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
-march=rv64gcv_zvl128b similar to below.
 
"error: invalid RVV vector size '128', expected size is '256' based on
LMUL of type and '-mrvv-vector-bits=zvl'"
 
For the vint*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
 
For the vfloat*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, -
 
For the vbool*_t types only below operations are allowed except
the CMP and ALU. The CMP and ALU operations on vbool*_t is not
well defined currently.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
 
For the vint*x*m*_t tuple types are not suppored in this patch
which is compatible with clang.
 
This patch passed the below testsuites.
* The riscv fully regression tests.
 
gcc/ChangeLog:
 
* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
New static func to take care of the RVV types decorated by
the attributes.
 
gcc/testsuite/ChangeLog:
 
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
 
Signed-off-by: Pan Li <pan2.li@intel.com>
---
gcc/config/riscv/riscv.cc                     |  88 +++++++++++++-
.../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
.../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
.../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
.../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
.../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
.../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
.../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
.../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
.../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
.../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
.../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
.../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
.../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
14 files changed, 600 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 56cd8d2c23f..fdbaf1633ac 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -535,6 +535,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
static bool riscv_avoid_shrink_wrapping_separate ();
static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
+static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
+     bool *);
/* Defining target-specific uses of __attribute__.  */
static const attribute_spec riscv_gnu_attributes[] =
@@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
     standard vector calling convention variant. Syntax:
     __attribute__((riscv_vector_cc)). */
-  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
};
static const scoped_attribute_specs riscv_gnu_attribute_table  =
@@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
      standard vector calling convention variant. Syntax:
      [[riscv::vector_cc]]. */
-  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
};
static const scoped_attribute_specs riscv_nongnu_attribute_table =
@@ -5561,6 +5583,68 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
   return NULL_TREE;
}
+static tree
+riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
+ ATTRIBUTE_UNUSED int flags,
+ bool *no_add_attrs)
+{
+  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
+    return NULL_TREE;
+
+  *no_add_attrs = true;
+
+  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
+    {
+      error (
+ "%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
+ "riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  tree type = *node;
+
+  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
+    {
+      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
+      return NULL_TREE;
+    }
+
+  tree size = TREE_VALUE (args);
+
+  if (TREE_CODE (size) != INTEGER_CST)
+    {
+      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
+  machine_mode mode = TYPE_MODE (type);
+  unsigned HOST_WIDE_INT type_mode_bits
+    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
+
+  if (args_in_bits != type_mode_bits)
+    {
+      error ("invalid RVV vector size %qd, "
+      "expected size is %qd based on LMUL of type and %qs",
+      (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
+      return NULL_TREE;
+    }
+
+  type = build_distinct_type_copy (type);
+  TYPE_ATTRIBUTES (type)
+    = remove_attribute ("RVV sizeless type",
+ copy_list (TYPE_ATTRIBUTES (type)));
+
+  /* The operations like alu/cmp on vbool*_t is not well defined,
+     continue to treat vbool*_t as indivisible.  */
+  if (!VECTOR_BOOLEAN_TYPE_P (type))
+    TYPE_INDIVISIBLE_P (type) = 0;
+
+  *node = type;
+
+  return NULL_TREE;
+}
+
/* Return true if function TYPE is an interrupt function.  */
static bool
riscv_interrupt_type_p (tree type)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
new file mode 100644
index 00000000000..8b08ba28130
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
new file mode 100644
index 00000000000..0ff48a29f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
new file mode 100644
index 00000000000..726c56b4a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
new file mode 100644
index 00000000000..5c2346dff3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
new file mode 100644
index 00000000000..6b841d7b1d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
new file mode 100644
index 00000000000..e1b0664eacb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
new file mode 100644
index 00000000000..eef15654110
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
new file mode 100644
index 00000000000..6b4f19cd9f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
new file mode 100644
index 00000000000..bc346917fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
new file mode 100644
index 00000000000..611a4bb88ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
new file mode 100644
index 00000000000..bb8d1da72b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
new file mode 100644
index 00000000000..701f833b41b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
new file mode 100644
index 00000000000..a7d68f2c36b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
@@ -0,0 +1,108 @@
+#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+
+#include "riscv_vector.h"
+#include "../autovec/vls/def.h"
+
+#define DEF_FIXED_TYPE(T, N)                                                   \
+  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
+
+#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
+  fixed_##T global_fixed_##T##_##N##_bits_var;
+
+#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
+  struct fixed_##T##_##N##_bits_struct                                         \
+  {                                                                            \
+    fixed_##T a, b[2];                                                         \
+  };
+
+#define DEF_FIXED_UNION_TYPE(T, N)                                             \
+  union fixed_##T##_##N##_bits_union                                           \
+  {                                                                            \
+    fixed_##T a, b[3];                                                         \
+  };
+
+#define TEST_FIXED_TYPE_SIZE(T, N)                                             \
+  void test_fixed_##T##_##N##_bits_size ()                                     \
+  {                                                                            \
+    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
+     "Fixed RVV register types should be equal.");              \
+  }
+
+#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                    \
+  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
+  {                                                                            \
+    return (NEW_TYPE) a;                                                       \
+  }
+
+#define TEST_FIXED_BINARY(T, N, OP, NAME)                                      \
+  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
+        fixed_##T b)            \
+  {                                                                            \
+    return a OP b;                                                             \
+  }
+
+#define TEST_FIXED_UNARY(T, N, OP, NAME)                                       \
+  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
+  {                                                                            \
+    return OP a;                                                               \
+  }
+
+#define TEST_FIXED_TYPE_CMP(T, N)                                              \
+  TEST_FIXED_BINARY(T, N, ==, eq)                                              \
+  TEST_FIXED_BINARY(T, N, !=, ne)                                              \
+  TEST_FIXED_BINARY(T, N, >,  gt)                                              \
+  TEST_FIXED_BINARY(T, N, <,  lt)                                              \
+  TEST_FIXED_BINARY(T, N, >=, ge)                                              \
+  TEST_FIXED_BINARY(T, N, <=, le)
+
+#define TEST_FIXED_TYPE_INT_ALU(T, N)                                          \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_BINARY(T, N, %,  mod)                                             \
+  TEST_FIXED_BINARY(T, N, &,  and)                                             \
+  TEST_FIXED_BINARY(T, N, |,  ior)                                             \
+  TEST_FIXED_BINARY(T, N, ^,  xor)                                             \
+  TEST_FIXED_BINARY(T, N, >>, rsh)                                             \
+  TEST_FIXED_BINARY(T, N, <<, lsh)                                             \
+  TEST_FIXED_UNARY(T, N, ~, not)                                               \
+  TEST_FIXED_UNARY(T, N, -, neg)
+
+#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                        \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_UNARY(T, N, -,  neg)
+
+#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_INT_ALU (T, N)                                               \
+
+#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                             \
+
+#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
+
+#endif
-- 
2.34.1
 
 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v2] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-06  6:38 [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV pan2.li
  2024-03-06  6:46 ` juzhe.zhong
@ 2024-03-06  7:27 ` pan2.li
  2024-03-06 19:19   ` Vineet Gupta
  2024-03-12  6:15 ` [PATCH v3] " pan2.li
  2024-03-22  6:54 ` [PATCH v4] " pan2.li
  3 siblings, 1 reply; 15+ messages in thread
From: pan2.li @ 2024-03-06  7:27 UTC (permalink / raw)
  To: gcc-patches
  Cc: juzhe.zhong, kito.cheng, yanzhang.wang, rdapp.gcc, vineetg,
	palmer, Pan Li

From: Pan Li <pan2.li@intel.com>

Update in v2:
* Cleanup some unused code.
* Fix some typo of commit log.

Original log:

This patch would like to introduce one new gcc attribute for RVV.
This attribute is used to define fixed-length variants of one
existing sizeless RVV types.

This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
one args should be the integer constant and its' value is terminated
by the LMUL and the vector register bits in zvl*b.  For example:

typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));

The above type define is valid when -march=rv64gc_zve64d_zvl64b
(aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
-march=rv64gcv_zvl128b similar to below.

"error: invalid RVV vector size '128', expected size is '256' based on
LMUL of type and '-mrvv-vector-bits=zvl'"

For the vint*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -

For the vfloat*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, -

For the vbool*_t types only below operations are allowed except
the CMP and ALU. The CMP and ALU operations on vbool*_t is not
well defined currently.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.

For the vint*x*m*_t tuple types are not suppored in this patch
which is compatible with clang.

This patch passed the below testsuites.
* The riscv fully regression tests.

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
	New static func to take care of the RVV types decorated by
	the attributes.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
 .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
 .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
 14 files changed, 599 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 56cd8d2c23f..9da8c638b91 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -535,6 +535,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
 static bool riscv_avoid_shrink_wrapping_separate ();
 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
+static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
+						    bool *);
 
 /* Defining target-specific uses of __attribute__.  */
 static const attribute_spec riscv_gnu_attributes[] =
@@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
     standard vector calling convention variant. Syntax:
     __attribute__((riscv_vector_cc)). */
-  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_gnu_attribute_table  =
@@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
      standard vector calling convention variant. Syntax:
      [[riscv::vector_cc]]. */
-  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_nongnu_attribute_table =
@@ -5561,6 +5583,67 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
   return NULL_TREE;
 }
 
+static tree
+riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
+					ATTRIBUTE_UNUSED int flags,
+					bool *no_add_attrs)
+{
+  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
+    return NULL_TREE;
+
+  *no_add_attrs = true;
+
+  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
+    {
+      error (
+	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
+	"riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  tree type = *node;
+
+  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
+    {
+      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
+      return NULL_TREE;
+    }
+
+  tree size = TREE_VALUE (args);
+
+  if (TREE_CODE (size) != INTEGER_CST)
+    {
+      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
+  unsigned HOST_WIDE_INT type_mode_bits
+    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
+
+  if (args_in_bits != type_mode_bits)
+    {
+      error ("invalid RVV vector size %qd, "
+	     "expected size is %qd based on LMUL of type and %qs",
+	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
+      return NULL_TREE;
+    }
+
+  type = build_distinct_type_copy (type);
+  TYPE_ATTRIBUTES (type)
+    = remove_attribute ("RVV sizeless type",
+			copy_list (TYPE_ATTRIBUTES (type)));
+
+  /* The operations like alu/cmp on vbool*_t is not well defined,
+     continue to treat vbool*_t as indivisible.  */
+  if (!VECTOR_BOOLEAN_TYPE_P (type))
+    TYPE_INDIVISIBLE_P (type) = 0;
+
+  *node = type;
+
+  return NULL_TREE;
+}
+
 /* Return true if function TYPE is an interrupt function.  */
 static bool
 riscv_interrupt_type_p (tree type)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
new file mode 100644
index 00000000000..8b08ba28130
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
new file mode 100644
index 00000000000..0ff48a29f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
new file mode 100644
index 00000000000..726c56b4a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
new file mode 100644
index 00000000000..5c2346dff3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
new file mode 100644
index 00000000000..6b841d7b1d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
new file mode 100644
index 00000000000..e1b0664eacb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
new file mode 100644
index 00000000000..eef15654110
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
new file mode 100644
index 00000000000..6b4f19cd9f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
new file mode 100644
index 00000000000..bc346917fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
new file mode 100644
index 00000000000..611a4bb88ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
new file mode 100644
index 00000000000..bb8d1da72b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
new file mode 100644
index 00000000000..701f833b41b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
new file mode 100644
index 00000000000..a7d68f2c36b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
@@ -0,0 +1,108 @@
+#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+
+#include "riscv_vector.h"
+#include "../autovec/vls/def.h"
+
+#define DEF_FIXED_TYPE(T, N)                                                   \
+  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
+
+#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
+  fixed_##T global_fixed_##T##_##N##_bits_var;
+
+#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
+  struct fixed_##T##_##N##_bits_struct                                         \
+  {                                                                            \
+    fixed_##T a, b[2];                                                         \
+  };
+
+#define DEF_FIXED_UNION_TYPE(T, N)                                             \
+  union fixed_##T##_##N##_bits_union                                           \
+  {                                                                            \
+    fixed_##T a, b[3];                                                         \
+  };
+
+#define TEST_FIXED_TYPE_SIZE(T, N)                                             \
+  void test_fixed_##T##_##N##_bits_size ()                                     \
+  {                                                                            \
+    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
+		    "Fixed RVV register types should be equal.");              \
+  }
+
+#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                    \
+  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
+  {                                                                            \
+    return (NEW_TYPE) a;                                                       \
+  }
+
+#define TEST_FIXED_BINARY(T, N, OP, NAME)                                      \
+  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
+						       fixed_##T b)            \
+  {                                                                            \
+    return a OP b;                                                             \
+  }
+
+#define TEST_FIXED_UNARY(T, N, OP, NAME)                                       \
+  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
+  {                                                                            \
+    return OP a;                                                               \
+  }
+
+#define TEST_FIXED_TYPE_CMP(T, N)                                              \
+  TEST_FIXED_BINARY(T, N, ==, eq)                                              \
+  TEST_FIXED_BINARY(T, N, !=, ne)                                              \
+  TEST_FIXED_BINARY(T, N, >,  gt)                                              \
+  TEST_FIXED_BINARY(T, N, <,  lt)                                              \
+  TEST_FIXED_BINARY(T, N, >=, ge)                                              \
+  TEST_FIXED_BINARY(T, N, <=, le)
+
+#define TEST_FIXED_TYPE_INT_ALU(T, N)                                          \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_BINARY(T, N, %,  mod)                                             \
+  TEST_FIXED_BINARY(T, N, &,  and)                                             \
+  TEST_FIXED_BINARY(T, N, |,  ior)                                             \
+  TEST_FIXED_BINARY(T, N, ^,  xor)                                             \
+  TEST_FIXED_BINARY(T, N, >>, rsh)                                             \
+  TEST_FIXED_BINARY(T, N, <<, lsh)                                             \
+  TEST_FIXED_UNARY(T, N, ~, not)                                               \
+  TEST_FIXED_UNARY(T, N, -, neg)
+
+#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                        \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_UNARY(T, N, -,  neg)
+
+#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_INT_ALU (T, N)                                               \
+
+#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                             \
+
+#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
+
+#endif
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v2] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-06  7:27 ` [PATCH v2] " pan2.li
@ 2024-03-06 19:19   ` Vineet Gupta
  2024-03-12  2:05     ` Li, Pan2
  0 siblings, 1 reply; 15+ messages in thread
From: Vineet Gupta @ 2024-03-06 19:19 UTC (permalink / raw)
  To: pan2.li, gcc-patches
  Cc: juzhe.zhong, kito.cheng, yanzhang.wang, rdapp.gcc, palmer



On 3/5/24 23:27, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@intel.com>
>
> Update in v2:
> * Cleanup some unused code.
> * Fix some typo of commit log.
>
> Original log:
>
> This patch would like to introduce one new gcc attribute for RVV.
> This attribute is used to define fixed-length variants of one
> existing sizeless RVV types.
>
> This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
> one args should be the integer constant and its' value is terminated
> by the LMUL and the vector register bits in zvl*b.  For example:
>
> typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
>
> The above type define is valid when -march=rv64gc_zve64d_zvl64b
> (aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
> -march=rv64gcv_zvl128b similar to below.
>
> "error: invalid RVV vector size '128', expected size is '256' based on
> LMUL of type and '-mrvv-vector-bits=zvl'"
>
> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, -
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
>
> For the vint*x*m*_t tuple types are not suppored in this patch
> which is compatible with clang.
>
> This patch passed the below testsuites.
> * The riscv fully regression tests.

While at it, can you also add the support for feature detection macro
|__riscv_v_fixed_vlen

Thx,
-Vineet
|

>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
> 	New static func to take care of the RVV types decorated by
> 	the attributes.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
>  .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
>  14 files changed, 599 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 56cd8d2c23f..9da8c638b91 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -535,6 +535,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
>  static bool riscv_avoid_shrink_wrapping_separate ();
>  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
>  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
> +static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
> +						    bool *);
>  
>  /* Defining target-specific uses of __attribute__.  */
>  static const attribute_spec riscv_gnu_attributes[] =
> @@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>      standard vector calling convention variant. Syntax:
>      __attribute__((riscv_vector_cc)). */
> -  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>  
>  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>       standard vector calling convention variant. Syntax:
>       [[riscv::vector_cc]]. */
> -  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>  
>  static const scoped_attribute_specs riscv_nongnu_attribute_table =
> @@ -5561,6 +5583,67 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
>    return NULL_TREE;
>  }
>  
> +static tree
> +riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
> +					ATTRIBUTE_UNUSED int flags,
> +					bool *no_add_attrs)
> +{
> +  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
> +    return NULL_TREE;
> +
> +  *no_add_attrs = true;
> +
> +  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
> +    {
> +      error (
> +	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
> +	"riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  tree type = *node;
> +
> +  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
> +    {
> +      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
> +      return NULL_TREE;
> +    }
> +
> +  tree size = TREE_VALUE (args);
> +
> +  if (TREE_CODE (size) != INTEGER_CST)
> +    {
> +      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
> +  unsigned HOST_WIDE_INT type_mode_bits
> +    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
> +
> +  if (args_in_bits != type_mode_bits)
> +    {
> +      error ("invalid RVV vector size %qd, "
> +	     "expected size is %qd based on LMUL of type and %qs",
> +	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
> +      return NULL_TREE;
> +    }
> +
> +  type = build_distinct_type_copy (type);
> +  TYPE_ATTRIBUTES (type)
> +    = remove_attribute ("RVV sizeless type",
> +			copy_list (TYPE_ATTRIBUTES (type)));
> +
> +  /* The operations like alu/cmp on vbool*_t is not well defined,
> +     continue to treat vbool*_t as indivisible.  */
> +  if (!VECTOR_BOOLEAN_TYPE_P (type))
> +    TYPE_INDIVISIBLE_P (type) = 0;
> +
> +  *node = type;
> +
> +  return NULL_TREE;
> +}
> +
>  /* Return true if function TYPE is an interrupt function.  */
>  static bool
>  riscv_interrupt_type_p (tree type)
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> new file mode 100644
> index 00000000000..8b08ba28130
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> new file mode 100644
> index 00000000000..0ff48a29f7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> new file mode 100644
> index 00000000000..726c56b4a7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> new file mode 100644
> index 00000000000..5c2346dff3e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> new file mode 100644
> index 00000000000..6b841d7b1d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> new file mode 100644
> index 00000000000..e1b0664eacb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> new file mode 100644
> index 00000000000..eef15654110
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> new file mode 100644
> index 00000000000..6b4f19cd9f2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> new file mode 100644
> index 00000000000..bc346917fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> new file mode 100644
> index 00000000000..611a4bb88ba
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> new file mode 100644
> index 00000000000..bb8d1da72b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> new file mode 100644
> index 00000000000..701f833b41b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> new file mode 100644
> index 00000000000..a7d68f2c36b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> @@ -0,0 +1,108 @@
> +#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +
> +#include "riscv_vector.h"
> +#include "../autovec/vls/def.h"
> +
> +#define DEF_FIXED_TYPE(T, N)                                                   \
> +  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
> +
> +#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
> +  fixed_##T global_fixed_##T##_##N##_bits_var;
> +
> +#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
> +  struct fixed_##T##_##N##_bits_struct                                         \
> +  {                                                                            \
> +    fixed_##T a, b[2];                                                         \
> +  };
> +
> +#define DEF_FIXED_UNION_TYPE(T, N)                                             \
> +  union fixed_##T##_##N##_bits_union                                           \
> +  {                                                                            \
> +    fixed_##T a, b[3];                                                         \
> +  };
> +
> +#define TEST_FIXED_TYPE_SIZE(T, N)                                             \
> +  void test_fixed_##T##_##N##_bits_size ()                                     \
> +  {                                                                            \
> +    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
> +		    "Fixed RVV register types should be equal.");              \
> +  }
> +
> +#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                    \
> +  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
> +  {                                                                            \
> +    return (NEW_TYPE) a;                                                       \
> +  }
> +
> +#define TEST_FIXED_BINARY(T, N, OP, NAME)                                      \
> +  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
> +						       fixed_##T b)            \
> +  {                                                                            \
> +    return a OP b;                                                             \
> +  }
> +
> +#define TEST_FIXED_UNARY(T, N, OP, NAME)                                       \
> +  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
> +  {                                                                            \
> +    return OP a;                                                               \
> +  }
> +
> +#define TEST_FIXED_TYPE_CMP(T, N)                                              \
> +  TEST_FIXED_BINARY(T, N, ==, eq)                                              \
> +  TEST_FIXED_BINARY(T, N, !=, ne)                                              \
> +  TEST_FIXED_BINARY(T, N, >,  gt)                                              \
> +  TEST_FIXED_BINARY(T, N, <,  lt)                                              \
> +  TEST_FIXED_BINARY(T, N, >=, ge)                                              \
> +  TEST_FIXED_BINARY(T, N, <=, le)
> +
> +#define TEST_FIXED_TYPE_INT_ALU(T, N)                                          \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                             \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                             \
> +  TEST_FIXED_BINARY(T, N, %,  mod)                                             \
> +  TEST_FIXED_BINARY(T, N, &,  and)                                             \
> +  TEST_FIXED_BINARY(T, N, |,  ior)                                             \
> +  TEST_FIXED_BINARY(T, N, ^,  xor)                                             \
> +  TEST_FIXED_BINARY(T, N, >>, rsh)                                             \
> +  TEST_FIXED_BINARY(T, N, <<, lsh)                                             \
> +  TEST_FIXED_UNARY(T, N, ~, not)                                               \
> +  TEST_FIXED_UNARY(T, N, -, neg)
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                        \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                             \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                             \
> +  TEST_FIXED_UNARY(T, N, -,  neg)
> +
> +#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                                   \
> +  TEST_FIXED_TYPE_INT_ALU (T, N)                                               \
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                                   \
> +  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                             \
> +
> +#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> +
> +#endif


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v2] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-06 19:19   ` Vineet Gupta
@ 2024-03-12  2:05     ` Li, Pan2
  0 siblings, 0 replies; 15+ messages in thread
From: Li, Pan2 @ 2024-03-12  2:05 UTC (permalink / raw)
  To: Vineet Gupta, gcc-patches, kito.cheng
  Cc: juzhe.zhong, Wang, Yanzhang, rdapp.gcc, palmer

Thanks Vinnet for reminder.

> While at it, can you also add the support for feature detection macro
> |__riscv_v_fixed_vlen

Kito told me that Greg will help to add that parts. Let's wait the comments from Kito.
Personally prefer a separated PATCH to cover that instead of appending here.

Pan

-----Original Message-----
From: Vineet Gupta <vineetg@rivosinc.com> 
Sent: Thursday, March 7, 2024 3:19 AM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org
Cc: juzhe.zhong@rivai.ai; kito.cheng@gmail.com; Wang, Yanzhang <yanzhang.wang@intel.com>; rdapp.gcc@gmail.com; palmer@rivosinc.com
Subject: Re: [PATCH v2] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV



On 3/5/24 23:27, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@intel.com>
>
> Update in v2:
> * Cleanup some unused code.
> * Fix some typo of commit log.
>
> Original log:
>
> This patch would like to introduce one new gcc attribute for RVV.
> This attribute is used to define fixed-length variants of one
> existing sizeless RVV types.
>
> This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
> one args should be the integer constant and its' value is terminated
> by the LMUL and the vector register bits in zvl*b.  For example:
>
> typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
>
> The above type define is valid when -march=rv64gc_zve64d_zvl64b
> (aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
> -march=rv64gcv_zvl128b similar to below.
>
> "error: invalid RVV vector size '128', expected size is '256' based on
> LMUL of type and '-mrvv-vector-bits=zvl'"
>
> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, -
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
>
> For the vint*x*m*_t tuple types are not suppored in this patch
> which is compatible with clang.
>
> This patch passed the below testsuites.
> * The riscv fully regression tests.

While at it, can you also add the support for feature detection macro
|__riscv_v_fixed_vlen

Thx,
-Vineet
|

>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
> 	New static func to take care of the RVV types decorated by
> 	the attributes.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
>  .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
>  14 files changed, 599 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
>
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 56cd8d2c23f..9da8c638b91 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -535,6 +535,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
>  static bool riscv_avoid_shrink_wrapping_separate ();
>  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
>  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
> +static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
> +						    bool *);
>  
>  /* Defining target-specific uses of __attribute__.  */
>  static const attribute_spec riscv_gnu_attributes[] =
> @@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>      standard vector calling convention variant. Syntax:
>      __attribute__((riscv_vector_cc)). */
> -  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>  
>  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>       standard vector calling convention variant. Syntax:
>       [[riscv::vector_cc]]. */
> -  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>  
>  static const scoped_attribute_specs riscv_nongnu_attribute_table =
> @@ -5561,6 +5583,67 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
>    return NULL_TREE;
>  }
>  
> +static tree
> +riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
> +					ATTRIBUTE_UNUSED int flags,
> +					bool *no_add_attrs)
> +{
> +  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
> +    return NULL_TREE;
> +
> +  *no_add_attrs = true;
> +
> +  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
> +    {
> +      error (
> +	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
> +	"riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  tree type = *node;
> +
> +  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
> +    {
> +      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
> +      return NULL_TREE;
> +    }
> +
> +  tree size = TREE_VALUE (args);
> +
> +  if (TREE_CODE (size) != INTEGER_CST)
> +    {
> +      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
> +  unsigned HOST_WIDE_INT type_mode_bits
> +    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
> +
> +  if (args_in_bits != type_mode_bits)
> +    {
> +      error ("invalid RVV vector size %qd, "
> +	     "expected size is %qd based on LMUL of type and %qs",
> +	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
> +      return NULL_TREE;
> +    }
> +
> +  type = build_distinct_type_copy (type);
> +  TYPE_ATTRIBUTES (type)
> +    = remove_attribute ("RVV sizeless type",
> +			copy_list (TYPE_ATTRIBUTES (type)));
> +
> +  /* The operations like alu/cmp on vbool*_t is not well defined,
> +     continue to treat vbool*_t as indivisible.  */
> +  if (!VECTOR_BOOLEAN_TYPE_P (type))
> +    TYPE_INDIVISIBLE_P (type) = 0;
> +
> +  *node = type;
> +
> +  return NULL_TREE;
> +}
> +
>  /* Return true if function TYPE is an interrupt function.  */
>  static bool
>  riscv_interrupt_type_p (tree type)
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> new file mode 100644
> index 00000000000..8b08ba28130
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> new file mode 100644
> index 00000000000..0ff48a29f7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> new file mode 100644
> index 00000000000..726c56b4a7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> new file mode 100644
> index 00000000000..5c2346dff3e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> new file mode 100644
> index 00000000000..6b841d7b1d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> new file mode 100644
> index 00000000000..e1b0664eacb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> new file mode 100644
> index 00000000000..eef15654110
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> new file mode 100644
> index 00000000000..6b4f19cd9f2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> new file mode 100644
> index 00000000000..bc346917fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> new file mode 100644
> index 00000000000..611a4bb88ba
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> new file mode 100644
> index 00000000000..bb8d1da72b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> new file mode 100644
> index 00000000000..701f833b41b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> new file mode 100644
> index 00000000000..a7d68f2c36b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> @@ -0,0 +1,108 @@
> +#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +
> +#include "riscv_vector.h"
> +#include "../autovec/vls/def.h"
> +
> +#define DEF_FIXED_TYPE(T, N)                                                   \
> +  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
> +
> +#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
> +  fixed_##T global_fixed_##T##_##N##_bits_var;
> +
> +#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
> +  struct fixed_##T##_##N##_bits_struct                                         \
> +  {                                                                            \
> +    fixed_##T a, b[2];                                                         \
> +  };
> +
> +#define DEF_FIXED_UNION_TYPE(T, N)                                             \
> +  union fixed_##T##_##N##_bits_union                                           \
> +  {                                                                            \
> +    fixed_##T a, b[3];                                                         \
> +  };
> +
> +#define TEST_FIXED_TYPE_SIZE(T, N)                                             \
> +  void test_fixed_##T##_##N##_bits_size ()                                     \
> +  {                                                                            \
> +    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
> +		    "Fixed RVV register types should be equal.");              \
> +  }
> +
> +#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                    \
> +  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
> +  {                                                                            \
> +    return (NEW_TYPE) a;                                                       \
> +  }
> +
> +#define TEST_FIXED_BINARY(T, N, OP, NAME)                                      \
> +  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
> +						       fixed_##T b)            \
> +  {                                                                            \
> +    return a OP b;                                                             \
> +  }
> +
> +#define TEST_FIXED_UNARY(T, N, OP, NAME)                                       \
> +  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
> +  {                                                                            \
> +    return OP a;                                                               \
> +  }
> +
> +#define TEST_FIXED_TYPE_CMP(T, N)                                              \
> +  TEST_FIXED_BINARY(T, N, ==, eq)                                              \
> +  TEST_FIXED_BINARY(T, N, !=, ne)                                              \
> +  TEST_FIXED_BINARY(T, N, >,  gt)                                              \
> +  TEST_FIXED_BINARY(T, N, <,  lt)                                              \
> +  TEST_FIXED_BINARY(T, N, >=, ge)                                              \
> +  TEST_FIXED_BINARY(T, N, <=, le)
> +
> +#define TEST_FIXED_TYPE_INT_ALU(T, N)                                          \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                             \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                             \
> +  TEST_FIXED_BINARY(T, N, %,  mod)                                             \
> +  TEST_FIXED_BINARY(T, N, &,  and)                                             \
> +  TEST_FIXED_BINARY(T, N, |,  ior)                                             \
> +  TEST_FIXED_BINARY(T, N, ^,  xor)                                             \
> +  TEST_FIXED_BINARY(T, N, >>, rsh)                                             \
> +  TEST_FIXED_BINARY(T, N, <<, lsh)                                             \
> +  TEST_FIXED_UNARY(T, N, ~, not)                                               \
> +  TEST_FIXED_UNARY(T, N, -, neg)
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                        \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                             \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                             \
> +  TEST_FIXED_UNARY(T, N, -,  neg)
> +
> +#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                                   \
> +  TEST_FIXED_TYPE_INT_ALU (T, N)                                               \
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                                   \
> +  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                             \
> +
> +#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> +
> +#endif


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-06  6:38 [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV pan2.li
  2024-03-06  6:46 ` juzhe.zhong
  2024-03-06  7:27 ` [PATCH v2] " pan2.li
@ 2024-03-12  6:15 ` pan2.li
  2024-03-12 13:25   ` Stefan O'Rear
  2024-03-21 13:25   ` Kito Cheng
  2024-03-22  6:54 ` [PATCH v4] " pan2.li
  3 siblings, 2 replies; 15+ messages in thread
From: pan2.li @ 2024-03-12  6:15 UTC (permalink / raw)
  To: gcc-patches
  Cc: juzhe.zhong, kito.cheng, yanzhang.wang, rdapp.gcc, vineetg,
	palmer, Pan Li

From: Pan Li <pan2.li@intel.com>

Update in v3:
* Add pre-defined __riscv_v_fixed_vlen when zvl.

Update in v2:
* Cleanup some unused code.
* Fix some typo of commit log.

Original log:

This patch would like to introduce one new gcc attribute for RVV.
This attribute is used to define fixed-length variants of one
existing sizeless RVV types.

This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
one args should be the integer constant and its' value is terminated
by the LMUL and the vector register bits in zvl*b.  For example:

typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));

The above type define is valid when -march=rv64gc_zve64d_zvl64b
(aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
-march=rv64gcv_zvl128b similar to below.

"error: invalid RVV vector size '128', expected size is '256' based on
LMUL of type and '-mrvv-vector-bits=zvl'"

Meanwhile, a pre-define macro __riscv_v_fixed_vlen is introduced to
represent the fixed vlen in a RVV vector register.

For the vint*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -

For the vfloat*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, -

For the vbool*_t types only below operations are allowed except
the CMP and ALU. The CMP and ALU operations on vbool*_t is not
well defined currently.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.

For the vint*x*m*_t tuple types are not suppored in this patch
which is compatible with clang.

This patch passed the below testsuites.
* The riscv fully regression tests.

gcc/ChangeLog:

	* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add pre-define
	macro __riscv_v_fixed_vlen when zvl.
	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
	New static func to take care of the RVV types decorated by
	the attributes.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv-c.cc                   |   3 +
 gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
 .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
 .../riscv/rvv/base/riscv_rvv_vector_bits-13.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-14.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-15.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-16.c |  11 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-17.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
 20 files changed, 653 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 3755ec0b8ef..d90be2ec0e8 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -140,6 +140,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
       builtin_define ("__riscv_vector");
       builtin_define_with_int_value ("__riscv_v_intrinsic",
 				     riscv_ext_version_value (0, 12));
+
+      if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
+	builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
     }
 
    if (TARGET_XTHEADVECTOR)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 680c4a728e9..0bc12d4f595 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -535,6 +535,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
 static bool riscv_avoid_shrink_wrapping_separate ();
 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
+static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
+						    bool *);
 
 /* Defining target-specific uses of __attribute__.  */
 static const attribute_spec riscv_gnu_attributes[] =
@@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
     standard vector calling convention variant. Syntax:
     __attribute__((riscv_vector_cc)). */
-  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_gnu_attribute_table  =
@@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
      standard vector calling convention variant. Syntax:
      [[riscv::vector_cc]]. */
-  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_nongnu_attribute_table =
@@ -5555,6 +5577,67 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
   return NULL_TREE;
 }
 
+static tree
+riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
+					ATTRIBUTE_UNUSED int flags,
+					bool *no_add_attrs)
+{
+  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
+    return NULL_TREE;
+
+  *no_add_attrs = true;
+
+  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
+    {
+      error (
+	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
+	"riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  tree type = *node;
+
+  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
+    {
+      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
+      return NULL_TREE;
+    }
+
+  tree size = TREE_VALUE (args);
+
+  if (TREE_CODE (size) != INTEGER_CST)
+    {
+      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
+  unsigned HOST_WIDE_INT type_mode_bits
+    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
+
+  if (args_in_bits != type_mode_bits)
+    {
+      error ("invalid RVV vector size %qd, "
+	     "expected size is %qd based on LMUL of type and %qs",
+	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
+      return NULL_TREE;
+    }
+
+  type = build_distinct_type_copy (type);
+  TYPE_ATTRIBUTES (type)
+    = remove_attribute ("RVV sizeless type",
+			copy_list (TYPE_ATTRIBUTES (type)));
+
+  /* The operations like alu/cmp on vbool*_t is not well defined,
+     continue to treat vbool*_t as indivisible.  */
+  if (!VECTOR_BOOLEAN_TYPE_P (type))
+    TYPE_INDIVISIBLE_P (type) = 0;
+
+  *node = type;
+
+  return NULL_TREE;
+}
+
 /* Return true if function TYPE is an interrupt function.  */
 static bool
 riscv_interrupt_type_p (tree type)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
new file mode 100644
index 00000000000..8b08ba28130
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
new file mode 100644
index 00000000000..0ff48a29f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
new file mode 100644
index 00000000000..726c56b4a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
new file mode 100644
index 00000000000..5c2346dff3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
new file mode 100644
index 00000000000..71d8b597da0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+void test () {
+
+#if defined __riscv_v_fixed_vlen
+#error "__riscv_v_fixed_vlen should not be defined"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
new file mode 100644
index 00000000000..b60ae4d20ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
+
+void test () {
+
+#if __riscv_v_fixed_vlen != 128
+#error "__riscv_v_fixed_vlen should be 128"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
new file mode 100644
index 00000000000..95edbbbd38d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
+
+void test () {
+
+#if __riscv_v_fixed_vlen != 512
+#error "__riscv_v_fixed_vlen should be 512"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
new file mode 100644
index 00000000000..df73f203791
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
@@ -0,0 +1,11 @@
+
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=scalable -O3" } */
+
+void test () {
+
+#if defined __riscv_v_fixed_vlen
+#error "__riscv_v_fixed_vlen should not be defined"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
new file mode 100644
index 00000000000..fa39a18d47c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
+
+void test () {
+
+#if __riscv_v_fixed_vlen != 4096
+#error "__riscv_v_fixed_vlen should be 4096"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
new file mode 100644
index 00000000000..6b841d7b1d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
new file mode 100644
index 00000000000..e1b0664eacb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
new file mode 100644
index 00000000000..eef15654110
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
new file mode 100644
index 00000000000..6b4f19cd9f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
new file mode 100644
index 00000000000..bc346917fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
new file mode 100644
index 00000000000..611a4bb88ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
new file mode 100644
index 00000000000..bb8d1da72b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
new file mode 100644
index 00000000000..701f833b41b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
new file mode 100644
index 00000000000..a7d68f2c36b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
@@ -0,0 +1,108 @@
+#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
+
+#include "riscv_vector.h"
+#include "../autovec/vls/def.h"
+
+#define DEF_FIXED_TYPE(T, N)                                                   \
+  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
+
+#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
+  fixed_##T global_fixed_##T##_##N##_bits_var;
+
+#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
+  struct fixed_##T##_##N##_bits_struct                                         \
+  {                                                                            \
+    fixed_##T a, b[2];                                                         \
+  };
+
+#define DEF_FIXED_UNION_TYPE(T, N)                                             \
+  union fixed_##T##_##N##_bits_union                                           \
+  {                                                                            \
+    fixed_##T a, b[3];                                                         \
+  };
+
+#define TEST_FIXED_TYPE_SIZE(T, N)                                             \
+  void test_fixed_##T##_##N##_bits_size ()                                     \
+  {                                                                            \
+    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
+		    "Fixed RVV register types should be equal.");              \
+  }
+
+#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                    \
+  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
+  {                                                                            \
+    return (NEW_TYPE) a;                                                       \
+  }
+
+#define TEST_FIXED_BINARY(T, N, OP, NAME)                                      \
+  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
+						       fixed_##T b)            \
+  {                                                                            \
+    return a OP b;                                                             \
+  }
+
+#define TEST_FIXED_UNARY(T, N, OP, NAME)                                       \
+  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
+  {                                                                            \
+    return OP a;                                                               \
+  }
+
+#define TEST_FIXED_TYPE_CMP(T, N)                                              \
+  TEST_FIXED_BINARY(T, N, ==, eq)                                              \
+  TEST_FIXED_BINARY(T, N, !=, ne)                                              \
+  TEST_FIXED_BINARY(T, N, >,  gt)                                              \
+  TEST_FIXED_BINARY(T, N, <,  lt)                                              \
+  TEST_FIXED_BINARY(T, N, >=, ge)                                              \
+  TEST_FIXED_BINARY(T, N, <=, le)
+
+#define TEST_FIXED_TYPE_INT_ALU(T, N)                                          \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_BINARY(T, N, %,  mod)                                             \
+  TEST_FIXED_BINARY(T, N, &,  and)                                             \
+  TEST_FIXED_BINARY(T, N, |,  ior)                                             \
+  TEST_FIXED_BINARY(T, N, ^,  xor)                                             \
+  TEST_FIXED_BINARY(T, N, >>, rsh)                                             \
+  TEST_FIXED_BINARY(T, N, <<, lsh)                                             \
+  TEST_FIXED_UNARY(T, N, ~, not)                                               \
+  TEST_FIXED_UNARY(T, N, -, neg)
+
+#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                        \
+  TEST_FIXED_BINARY(T, N, +,  add)                                             \
+  TEST_FIXED_BINARY(T, N, -,  sub)                                             \
+  TEST_FIXED_BINARY(T, N, *,  mul)                                             \
+  TEST_FIXED_BINARY(T, N, /,  div)                                             \
+  TEST_FIXED_UNARY(T, N, -,  neg)
+
+#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_INT_ALU (T, N)                                               \
+
+#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                         \
+  TEST_FIXED_TYPE_CMP (T, N)                                                   \
+  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                             \
+
+#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  TEST_FIXED_TYPE_SIZE (T, N)                                                  \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
+
+#endif
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-12  6:15 ` [PATCH v3] " pan2.li
@ 2024-03-12 13:25   ` Stefan O'Rear
  2024-03-15  1:45     ` Li, Pan2
  2024-03-21 13:25   ` Kito Cheng
  1 sibling, 1 reply; 15+ messages in thread
From: Stefan O'Rear @ 2024-03-12 13:25 UTC (permalink / raw)
  To: Pan2 Li, gcc-patches
  Cc: juzhe.zhong, Kito Cheng, Yanzhang Wang, rdapp.gcc, Vineet Gupta,
	Palmer Dabbelt

On Tue, Mar 12, 2024, at 2:15 AM, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@intel.com>
>
> Update in v3:
> * Add pre-defined __riscv_v_fixed_vlen when zvl.
>
> Update in v2:
> * Cleanup some unused code.
> * Fix some typo of commit log.
>
> Original log:
>
> This patch would like to introduce one new gcc attribute for RVV.
> This attribute is used to define fixed-length variants of one
> existing sizeless RVV types.
>
> This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
> one args should be the integer constant and its' value is terminated
> by the LMUL and the vector register bits in zvl*b.  For example:
>
> typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
>
> The above type define is valid when -march=rv64gc_zve64d_zvl64b
> (aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
> -march=rv64gcv_zvl128b similar to below.
>
> "error: invalid RVV vector size '128', expected size is '256' based on
> LMUL of type and '-mrvv-vector-bits=zvl'"
>
> Meanwhile, a pre-define macro __riscv_v_fixed_vlen is introduced to
> represent the fixed vlen in a RVV vector register.

Shouldn't a major user-facing change like this be discussed in a PR against
https://github.com/riscv-non-isa/riscv-c-api-doc/ or
https://github.com/riscv-non-isa/rvv-intrinsic-doc before or concurrent with
compiler implementation?

-s

> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, -
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
>
> For the vint*x*m*_t tuple types are not suppored in this patch
> which is compatible with clang.
>
> This patch passed the below testsuites.
> * The riscv fully regression tests.
>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add pre-define
> 	macro __riscv_v_fixed_vlen when zvl.
> 	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
> 	New static func to take care of the RVV types decorated by
> 	the attributes.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-c.cc                   |   3 +
>  gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
>  .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-13.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-14.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-15.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-16.c |  11 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-17.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
>  20 files changed, 653 insertions(+), 2 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
>
> diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> index 3755ec0b8ef..d90be2ec0e8 100644
> --- a/gcc/config/riscv/riscv-c.cc
> +++ b/gcc/config/riscv/riscv-c.cc
> @@ -140,6 +140,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
>        builtin_define ("__riscv_vector");
>        builtin_define_with_int_value ("__riscv_v_intrinsic",
>  				     riscv_ext_version_value (0, 12));
> +
> +      if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
> +	builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
>      }
> 
>     if (TARGET_XTHEADVECTOR)
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 680c4a728e9..0bc12d4f595 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -535,6 +535,8 @@ static const struct riscv_tune_param 
> optimize_size_tune_info = {
>  static bool riscv_avoid_shrink_wrapping_separate ();
>  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, 
> bool *);
>  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool 
> *);
> +static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, 
> tree, int,
> +						    bool *);
> 
>  /* Defining target-specific uses of __attribute__.  */
>  static const attribute_spec riscv_gnu_attributes[] =
> @@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>      standard vector calling convention variant. Syntax:
>      __attribute__((riscv_vector_cc)). */
> -  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
> 
>  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>       standard vector calling convention variant. Syntax:
>       [[riscv::vector_cc]]. */
> -  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
> 
>  static const scoped_attribute_specs riscv_nongnu_attribute_table =
> @@ -5555,6 +5577,67 @@ riscv_handle_type_attribute (tree *node 
> ATTRIBUTE_UNUSED, tree name, tree args,
>    return NULL_TREE;
>  }
> 
> +static tree
> +riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree 
> args,
> +					ATTRIBUTE_UNUSED int flags,
> +					bool *no_add_attrs)
> +{
> +  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
> +    return NULL_TREE;
> +
> +  *no_add_attrs = true;
> +
> +  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
> +    {
> +      error (
> +	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
> +	"riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  tree type = *node;
> +
> +  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
> +    {
> +      error ("%qs applied to non-RVV type %qT", 
> "riscv_rvv_vector_bits", type);
> +      return NULL_TREE;
> +    }
> +
> +  tree size = TREE_VALUE (args);
> +
> +  if (TREE_CODE (size) != INTEGER_CST)
> +    {
> +      error ("%qs requires an integer constant", 
> "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
> +  unsigned HOST_WIDE_INT type_mode_bits
> +    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
> +
> +  if (args_in_bits != type_mode_bits)
> +    {
> +      error ("invalid RVV vector size %qd, "
> +	     "expected size is %qd based on LMUL of type and %qs",
> +	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
> +      return NULL_TREE;
> +    }
> +
> +  type = build_distinct_type_copy (type);
> +  TYPE_ATTRIBUTES (type)
> +    = remove_attribute ("RVV sizeless type",
> +			copy_list (TYPE_ATTRIBUTES (type)));
> +
> +  /* The operations like alu/cmp on vbool*_t is not well defined,
> +     continue to treat vbool*_t as indivisible.  */
> +  if (!VECTOR_BOOLEAN_TYPE_P (type))
> +    TYPE_INDIVISIBLE_P (type) = 0;
> +
> +  *node = type;
> +
> +  return NULL_TREE;
> +}
> +
>  /* Return true if function TYPE is an interrupt function.  */
>  static bool
>  riscv_interrupt_type_p (tree type)
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> new file mode 100644
> index 00000000000..8b08ba28130
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" 
> } */
> +
> +#include "riscv_vector.h"
> +
> +typedef int fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error 
> "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> new file mode 100644
> index 00000000000..0ff48a29f7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> new file mode 100644
> index 00000000000..726c56b4a7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> new file mode 100644
> index 00000000000..5c2346dff3e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> new file mode 100644
> index 00000000000..71d8b597da0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> new file mode 100644
> index 00000000000..b60ae4d20ff
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -mrvv-vector-bits=zvl" 
> } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 128
> +#error "__riscv_v_fixed_vlen should be 128"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> new file mode 100644
> index 00000000000..95edbbbd38d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3 
> -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 512
> +#error "__riscv_v_fixed_vlen should be 512"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> new file mode 100644
> index 00000000000..df73f203791
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> @@ -0,0 +1,11 @@
> +
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d 
> -mrvv-vector-bits=scalable -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> new file mode 100644
> index 00000000000..fa39a18d47c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 
> -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 4096
> +#error "__riscv_v_fixed_vlen should be 4096"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> new file mode 100644
> index 00000000000..6b841d7b1d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" 
> } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error 
> "'riscv_rvv_vector_bits' requires an integer constant" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> new file mode 100644
> index 00000000000..e1b0664eacb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error 
> "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' 
> is specified" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> new file mode 100644
> index 00000000000..eef15654110
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV 
> vector size '128', expected size is '256' based on LMUL of type and 
> '-mrvv-vector-bits=zvl'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> new file mode 100644
> index 00000000000..6b4f19cd9f2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m2_t fixed_vint32m2_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV 
> vector size '128', expected size is '256' based on LMUL of type and 
> '-mrvv-vector-bits=zvl'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> new file mode 100644
> index 00000000000..bc346917fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32mf2_t fixed_vint32mf2_t 
> __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV 
> vector size '256', expected size is '128' based on LMUL of type and 
> '-mrvv-vector-bits=zvl'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> new file mode 100644
> index 00000000000..611a4bb88ba
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> new file mode 100644
> index 00000000000..bb8d1da72b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> new file mode 100644
> index 00000000000..701f833b41b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> new file mode 100644
> index 00000000000..a7d68f2c36b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> @@ -0,0 +1,108 @@
> +#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +
> +#include "riscv_vector.h"
> +#include "../autovec/vls/def.h"
> +
> +#define DEF_FIXED_TYPE(T, N)                                           
>         \
> +  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
> +
> +#define DEF_FIXED_GLOBAL_VAR(T, N)                                     
>         \
> +  fixed_##T global_fixed_##T##_##N##_bits_var;
> +
> +#define DEF_FIXED_STRUCT_TYPE(T, N)                                    
>         \
> +  struct fixed_##T##_##N##_bits_struct                                 
>         \
> +  {                                                                    
>         \
> +    fixed_##T a, b[2];                                                 
>         \
> +  };
> +
> +#define DEF_FIXED_UNION_TYPE(T, N)                                     
>         \
> +  union fixed_##T##_##N##_bits_union                                   
>         \
> +  {                                                                    
>         \
> +    fixed_##T a, b[3];                                                 
>         \
> +  };
> +
> +#define TEST_FIXED_TYPE_SIZE(T, N)                                     
>         \
> +  void test_fixed_##T##_##N##_bits_size ()                             
>         \
> +  {                                                                    
>         \
> +    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),         
>         \
> +		    "Fixed RVV register types should be equal.");              \
> +  }
> +
> +#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                            
>         \
> +  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)               
>         \
> +  {                                                                    
>         \
> +    return (NEW_TYPE) a;                                               
>         \
> +  }
> +
> +#define TEST_FIXED_BINARY(T, N, OP, NAME)                              
>         \
> +  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,    
>         \
> +						       fixed_##T b)            \
> +  {                                                                    
>         \
> +    return a OP b;                                                     
>         \
> +  }
> +
> +#define TEST_FIXED_UNARY(T, N, OP, NAME)                               
>         \
> +  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)     
>         \
> +  {                                                                    
>         \
> +    return OP a;                                                       
>         \
> +  }
> +
> +#define TEST_FIXED_TYPE_CMP(T, N)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, ==, eq)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, !=, ne)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, >,  gt)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, <,  lt)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, >=, ge)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, <=, le)
> +
> +#define TEST_FIXED_TYPE_INT_ALU(T, N)                                  
>         \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, %,  mod)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, &,  and)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, |,  ior)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, ^,  xor)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, >>, rsh)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, <<, lsh)                                     
>         \
> +  TEST_FIXED_UNARY(T, N, ~, not)                                       
>         \
> +  TEST_FIXED_UNARY(T, N, -, neg)
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                
>         \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                     
>         \
> +  TEST_FIXED_UNARY(T, N, -,  neg)
> +
> +#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                        
>         \
> +  DEF_FIXED_TYPE (T, N)                                                
>         \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                          
>         \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                          
>         \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                         
>         \
> +  DEF_FIXED_UNION_TYPE (T, N)                                          
>         \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                 
>         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                           
>         \
> +  TEST_FIXED_TYPE_INT_ALU (T, N)                                       
>         \
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                      
>         \
> +  DEF_FIXED_TYPE (T, N)                                                
>         \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                          
>         \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                          
>         \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                         
>         \
> +  DEF_FIXED_UNION_TYPE (T, N)                                          
>         \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                 
>         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                           
>         \
> +  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                     
>         \
> +
> +#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                       
>         \
> +  DEF_FIXED_TYPE (T, N)                                                
>         \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                          
>         \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                          
>         \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                         
>         \
> +  DEF_FIXED_UNION_TYPE (T, N)                                          
>         \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> +
> +#endif
> -- 
> 2.34.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-12 13:25   ` Stefan O'Rear
@ 2024-03-15  1:45     ` Li, Pan2
  2024-03-21 13:28       ` Kito Cheng
  0 siblings, 1 reply; 15+ messages in thread
From: Li, Pan2 @ 2024-03-15  1:45 UTC (permalink / raw)
  To: Stefan O'Rear, gcc-patches, Kito Cheng
  Cc: juzhe.zhong, Wang, Yanzhang, rdapp.gcc, Vineet Gupta, Palmer Dabbelt

> Shouldn't a major user-facing change like this be discussed in a PR against
> https://github.com/riscv-non-isa/riscv-c-api-doc/ or
> https://github.com/riscv-non-isa/rvv-intrinsic-doc before or concurrent with
> compiler implementation?

I think Kito is working on the spec doc already.

Hi Kito
Could you please help to correct me the behavior of the riscv_rvv_vector_bits attribute?
Sort of details and I suspect there is something missing, or different behavior compared with clang side.

Pan

-----Original Message-----
From: Stefan O'Rear <sorear@fastmail.com> 
Sent: Tuesday, March 12, 2024 9:25 PM
To: Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org
Cc: juzhe.zhong@rivai.ai; Kito Cheng <kito.cheng@gmail.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; rdapp.gcc@gmail.com; Vineet Gupta <vineetg@rivosinc.com>; Palmer Dabbelt <palmer@rivosinc.com>
Subject: Re: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV

On Tue, Mar 12, 2024, at 2:15 AM, pan2.li@intel.com wrote:
> From: Pan Li <pan2.li@intel.com>
>
> Update in v3:
> * Add pre-defined __riscv_v_fixed_vlen when zvl.
>
> Update in v2:
> * Cleanup some unused code.
> * Fix some typo of commit log.
>
> Original log:
>
> This patch would like to introduce one new gcc attribute for RVV.
> This attribute is used to define fixed-length variants of one
> existing sizeless RVV types.
>
> This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
> one args should be the integer constant and its' value is terminated
> by the LMUL and the vector register bits in zvl*b.  For example:
>
> typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
>
> The above type define is valid when -march=rv64gc_zve64d_zvl64b
> (aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
> -march=rv64gcv_zvl128b similar to below.
>
> "error: invalid RVV vector size '128', expected size is '256' based on
> LMUL of type and '-mrvv-vector-bits=zvl'"
>
> Meanwhile, a pre-define macro __riscv_v_fixed_vlen is introduced to
> represent the fixed vlen in a RVV vector register.

Shouldn't a major user-facing change like this be discussed in a PR against
https://github.com/riscv-non-isa/riscv-c-api-doc/ or
https://github.com/riscv-non-isa/rvv-intrinsic-doc before or concurrent with
compiler implementation?

-s

> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, -
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
>
> For the vint*x*m*_t tuple types are not suppored in this patch
> which is compatible with clang.
>
> This patch passed the below testsuites.
> * The riscv fully regression tests.
>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add pre-define
> 	macro __riscv_v_fixed_vlen when zvl.
> 	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
> 	New static func to take care of the RVV types decorated by
> 	the attributes.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
> 	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-c.cc                   |   3 +
>  gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
>  .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-13.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-14.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-15.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-16.c |  11 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-17.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
>  20 files changed, 653 insertions(+), 2 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
>  create mode 100644 
> gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
>
> diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> index 3755ec0b8ef..d90be2ec0e8 100644
> --- a/gcc/config/riscv/riscv-c.cc
> +++ b/gcc/config/riscv/riscv-c.cc
> @@ -140,6 +140,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
>        builtin_define ("__riscv_vector");
>        builtin_define_with_int_value ("__riscv_v_intrinsic",
>  				     riscv_ext_version_value (0, 12));
> +
> +      if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
> +	builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
>      }
> 
>     if (TARGET_XTHEADVECTOR)
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 680c4a728e9..0bc12d4f595 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -535,6 +535,8 @@ static const struct riscv_tune_param 
> optimize_size_tune_info = {
>  static bool riscv_avoid_shrink_wrapping_separate ();
>  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, 
> bool *);
>  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool 
> *);
> +static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, 
> tree, int,
> +						    bool *);
> 
>  /* Defining target-specific uses of __attribute__.  */
>  static const attribute_spec riscv_gnu_attributes[] =
> @@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>      standard vector calling convention variant. Syntax:
>      __attribute__((riscv_vector_cc)). */
> -  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
> 
>  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>       standard vector calling convention variant. Syntax:
>       [[riscv::vector_cc]]. */
> -  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
> 
>  static const scoped_attribute_specs riscv_nongnu_attribute_table =
> @@ -5555,6 +5577,67 @@ riscv_handle_type_attribute (tree *node 
> ATTRIBUTE_UNUSED, tree name, tree args,
>    return NULL_TREE;
>  }
> 
> +static tree
> +riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree 
> args,
> +					ATTRIBUTE_UNUSED int flags,
> +					bool *no_add_attrs)
> +{
> +  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
> +    return NULL_TREE;
> +
> +  *no_add_attrs = true;
> +
> +  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
> +    {
> +      error (
> +	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
> +	"riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  tree type = *node;
> +
> +  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
> +    {
> +      error ("%qs applied to non-RVV type %qT", 
> "riscv_rvv_vector_bits", type);
> +      return NULL_TREE;
> +    }
> +
> +  tree size = TREE_VALUE (args);
> +
> +  if (TREE_CODE (size) != INTEGER_CST)
> +    {
> +      error ("%qs requires an integer constant", 
> "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
> +  unsigned HOST_WIDE_INT type_mode_bits
> +    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
> +
> +  if (args_in_bits != type_mode_bits)
> +    {
> +      error ("invalid RVV vector size %qd, "
> +	     "expected size is %qd based on LMUL of type and %qs",
> +	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
> +      return NULL_TREE;
> +    }
> +
> +  type = build_distinct_type_copy (type);
> +  TYPE_ATTRIBUTES (type)
> +    = remove_attribute ("RVV sizeless type",
> +			copy_list (TYPE_ATTRIBUTES (type)));
> +
> +  /* The operations like alu/cmp on vbool*_t is not well defined,
> +     continue to treat vbool*_t as indivisible.  */
> +  if (!VECTOR_BOOLEAN_TYPE_P (type))
> +    TYPE_INDIVISIBLE_P (type) = 0;
> +
> +  *node = type;
> +
> +  return NULL_TREE;
> +}
> +
>  /* Return true if function TYPE is an interrupt function.  */
>  static bool
>  riscv_interrupt_type_p (tree type)
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> new file mode 100644
> index 00000000000..8b08ba28130
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" 
> } */
> +
> +#include "riscv_vector.h"
> +
> +typedef int fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error 
> "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> new file mode 100644
> index 00000000000..0ff48a29f7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> new file mode 100644
> index 00000000000..726c56b4a7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> new file mode 100644
> index 00000000000..5c2346dff3e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> new file mode 100644
> index 00000000000..71d8b597da0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> new file mode 100644
> index 00000000000..b60ae4d20ff
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -mrvv-vector-bits=zvl" 
> } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 128
> +#error "__riscv_v_fixed_vlen should be 128"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> new file mode 100644
> index 00000000000..95edbbbd38d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3 
> -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 512
> +#error "__riscv_v_fixed_vlen should be 512"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> new file mode 100644
> index 00000000000..df73f203791
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> @@ -0,0 +1,11 @@
> +
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d 
> -mrvv-vector-bits=scalable -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> new file mode 100644
> index 00000000000..fa39a18d47c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 
> -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 4096
> +#error "__riscv_v_fixed_vlen should be 4096"
> +#endif
> +
> +}
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> new file mode 100644
> index 00000000000..6b841d7b1d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" 
> } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error 
> "'riscv_rvv_vector_bits' requires an integer constant" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> new file mode 100644
> index 00000000000..e1b0664eacb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error 
> "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' 
> is specified" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> new file mode 100644
> index 00000000000..eef15654110
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV 
> vector size '128', expected size is '256' based on LMUL of type and 
> '-mrvv-vector-bits=zvl'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> new file mode 100644
> index 00000000000..6b4f19cd9f2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m2_t fixed_vint32m2_t 
> __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV 
> vector size '128', expected size is '256' based on LMUL of type and 
> '-mrvv-vector-bits=zvl'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> new file mode 100644
> index 00000000000..bc346917fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32mf2_t fixed_vint32mf2_t 
> __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV 
> vector size '256', expected size is '128' based on LMUL of type and 
> '-mrvv-vector-bits=zvl'" } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> new file mode 100644
> index 00000000000..611a4bb88ba
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> new file mode 100644
> index 00000000000..bb8d1da72b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> new file mode 100644
> index 00000000000..701f833b41b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 
> -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git 
> a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h 
> b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> new file mode 100644
> index 00000000000..a7d68f2c36b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> @@ -0,0 +1,108 @@
> +#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> +
> +#include "riscv_vector.h"
> +#include "../autovec/vls/def.h"
> +
> +#define DEF_FIXED_TYPE(T, N)                                           
>         \
> +  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
> +
> +#define DEF_FIXED_GLOBAL_VAR(T, N)                                     
>         \
> +  fixed_##T global_fixed_##T##_##N##_bits_var;
> +
> +#define DEF_FIXED_STRUCT_TYPE(T, N)                                    
>         \
> +  struct fixed_##T##_##N##_bits_struct                                 
>         \
> +  {                                                                    
>         \
> +    fixed_##T a, b[2];                                                 
>         \
> +  };
> +
> +#define DEF_FIXED_UNION_TYPE(T, N)                                     
>         \
> +  union fixed_##T##_##N##_bits_union                                   
>         \
> +  {                                                                    
>         \
> +    fixed_##T a, b[3];                                                 
>         \
> +  };
> +
> +#define TEST_FIXED_TYPE_SIZE(T, N)                                     
>         \
> +  void test_fixed_##T##_##N##_bits_size ()                             
>         \
> +  {                                                                    
>         \
> +    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),         
>         \
> +		    "Fixed RVV register types should be equal.");              \
> +  }
> +
> +#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)                            
>         \
> +  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)               
>         \
> +  {                                                                    
>         \
> +    return (NEW_TYPE) a;                                               
>         \
> +  }
> +
> +#define TEST_FIXED_BINARY(T, N, OP, NAME)                              
>         \
> +  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,    
>         \
> +						       fixed_##T b)            \
> +  {                                                                    
>         \
> +    return a OP b;                                                     
>         \
> +  }
> +
> +#define TEST_FIXED_UNARY(T, N, OP, NAME)                               
>         \
> +  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)     
>         \
> +  {                                                                    
>         \
> +    return OP a;                                                       
>         \
> +  }
> +
> +#define TEST_FIXED_TYPE_CMP(T, N)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, ==, eq)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, !=, ne)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, >,  gt)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, <,  lt)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, >=, ge)                                      
>         \
> +  TEST_FIXED_BINARY(T, N, <=, le)
> +
> +#define TEST_FIXED_TYPE_INT_ALU(T, N)                                  
>         \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, %,  mod)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, &,  and)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, |,  ior)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, ^,  xor)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, >>, rsh)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, <<, lsh)                                     
>         \
> +  TEST_FIXED_UNARY(T, N, ~, not)                                       
>         \
> +  TEST_FIXED_UNARY(T, N, -, neg)
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)                                
>         \
> +  TEST_FIXED_BINARY(T, N, +,  add)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, -,  sub)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, *,  mul)                                     
>         \
> +  TEST_FIXED_BINARY(T, N, /,  div)                                     
>         \
> +  TEST_FIXED_UNARY(T, N, -,  neg)
> +
> +#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                        
>         \
> +  DEF_FIXED_TYPE (T, N)                                                
>         \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                          
>         \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                          
>         \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                         
>         \
> +  DEF_FIXED_UNION_TYPE (T, N)                                          
>         \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                 
>         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                           
>         \
> +  TEST_FIXED_TYPE_INT_ALU (T, N)                                       
>         \
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                      
>         \
> +  DEF_FIXED_TYPE (T, N)                                                
>         \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                          
>         \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                          
>         \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                         
>         \
> +  DEF_FIXED_UNION_TYPE (T, N)                                          
>         \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                 
>         \
> +  TEST_FIXED_TYPE_CMP (T, N)                                           
>         \
> +  TEST_FIXED_TYPE_FLOAT_ALU (T, N)                                     
>         \
> +
> +#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                       
>         \
> +  DEF_FIXED_TYPE (T, N)                                                
>         \
> +  TEST_FIXED_TYPE_SIZE (T, N)                                          
>         \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                          
>         \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                         
>         \
> +  DEF_FIXED_UNION_TYPE (T, N)                                          
>         \
> +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> +
> +#endif
> -- 
> 2.34.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-12  6:15 ` [PATCH v3] " pan2.li
  2024-03-12 13:25   ` Stefan O'Rear
@ 2024-03-21 13:25   ` Kito Cheng
  2024-03-21 14:11     ` Li, Pan2
  1 sibling, 1 reply; 15+ messages in thread
From: Kito Cheng @ 2024-03-21 13:25 UTC (permalink / raw)
  To: pan2.li
  Cc: gcc-patches, juzhe.zhong, yanzhang.wang, rdapp.gcc, vineetg, palmer

> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=

The result of comparison should be vbool* rather than v[u]int*.

> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=

The result of comparison should be vbool* rather than vfloat*,
otherwise all 1 is not really meanful for floating point value.

But I know clang generates the same strange/wrong code here...

> * ALU: +, -, *, /, -
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.

&, ^, | has supported on clang, so I think we should support that as well

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-15  1:45     ` Li, Pan2
@ 2024-03-21 13:28       ` Kito Cheng
  0 siblings, 0 replies; 15+ messages in thread
From: Kito Cheng @ 2024-03-21 13:28 UTC (permalink / raw)
  To: Li, Pan2
  Cc: Stefan O'Rear, gcc-patches, juzhe.zhong, Wang, Yanzhang,
	rdapp.gcc, Vineet Gupta, Palmer Dabbelt

Hi Stefan:

I admit that's kinda bad practice here, the spec should appear before
implementation or at least come together, however we have long
discussion on the RISC-V gcc community on this, and we give a waiver
for this feature due to the clang compatibility, and this features
also used on some project, so we would like to moving this forward
even it's incomplete.

For the spec part, we are working in progress and will put the draft soon.

On Fri, Mar 15, 2024 at 9:46 AM Li, Pan2 <pan2.li@intel.com> wrote:
>
> > Shouldn't a major user-facing change like this be discussed in a PR against
> > https://github.com/riscv-non-isa/riscv-c-api-doc/ or
> > https://github.com/riscv-non-isa/rvv-intrinsic-doc before or concurrent with
> > compiler implementation?
>
> I think Kito is working on the spec doc already.
>
> Hi Kito
> Could you please help to correct me the behavior of the riscv_rvv_vector_bits attribute?
> Sort of details and I suspect there is something missing, or different behavior compared with clang side.
>
> Pan
>
> -----Original Message-----
> From: Stefan O'Rear <sorear@fastmail.com>
> Sent: Tuesday, March 12, 2024 9:25 PM
> To: Li, Pan2 <pan2.li@intel.com>; gcc-patches@gcc.gnu.org
> Cc: juzhe.zhong@rivai.ai; Kito Cheng <kito.cheng@gmail.com>; Wang, Yanzhang <yanzhang.wang@intel.com>; rdapp.gcc@gmail.com; Vineet Gupta <vineetg@rivosinc.com>; Palmer Dabbelt <palmer@rivosinc.com>
> Subject: Re: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
>
> On Tue, Mar 12, 2024, at 2:15 AM, pan2.li@intel.com wrote:
> > From: Pan Li <pan2.li@intel.com>
> >
> > Update in v3:
> > * Add pre-defined __riscv_v_fixed_vlen when zvl.
> >
> > Update in v2:
> > * Cleanup some unused code.
> > * Fix some typo of commit log.
> >
> > Original log:
> >
> > This patch would like to introduce one new gcc attribute for RVV.
> > This attribute is used to define fixed-length variants of one
> > existing sizeless RVV types.
> >
> > This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
> > one args should be the integer constant and its' value is terminated
> > by the LMUL and the vector register bits in zvl*b.  For example:
> >
> > typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
> >
> > The above type define is valid when -march=rv64gc_zve64d_zvl64b
> > (aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
> > -march=rv64gcv_zvl128b similar to below.
> >
> > "error: invalid RVV vector size '128', expected size is '256' based on
> > LMUL of type and '-mrvv-vector-bits=zvl'"
> >
> > Meanwhile, a pre-define macro __riscv_v_fixed_vlen is introduced to
> > represent the fixed vlen in a RVV vector register.
>
> Shouldn't a major user-facing change like this be discussed in a PR against
> https://github.com/riscv-non-isa/riscv-c-api-doc/ or
> https://github.com/riscv-non-isa/rvv-intrinsic-doc before or concurrent with
> compiler implementation?
>
> -s
>
> > For the vint*m*_t below operations are allowed.
> > * The sizeof.
> > * The global variable(s).
> > * The element of union and struct.
> > * The cast to other equalities.
> > * CMP: >, <, ==, !=, <=, >=
> > * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
> >
> > For the vfloat*m*_t below operations are allowed.
> > * The sizeof.
> > * The global variable(s).
> > * The element of union and struct.
> > * The cast to other equalities.
> > * CMP: >, <, ==, !=, <=, >=
> > * ALU: +, -, *, /, -
> >
> > For the vbool*_t types only below operations are allowed except
> > the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> > well defined currently.
> > * The sizeof.
> > * The global variable(s).
> > * The element of union and struct.
> > * The cast to other equalities.
> >
> > For the vint*x*m*_t tuple types are not suppored in this patch
> > which is compatible with clang.
> >
> > This patch passed the below testsuites.
> > * The riscv fully regression tests.
> >
> > gcc/ChangeLog:
> >
> >       * config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add pre-define
> >       macro __riscv_v_fixed_vlen when zvl.
> >       * config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
> >       New static func to take care of the RVV types decorated by
> >       the attributes.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
> >       * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
> >
> > Signed-off-by: Pan Li <pan2.li@intel.com>
> > ---
> >  gcc/config/riscv/riscv-c.cc                   |   3 +
> >  gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-13.c |  10 ++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-14.c |  10 ++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-15.c |  10 ++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-16.c |  11 ++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-17.c |  10 ++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
> >  .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
> >  20 files changed, 653 insertions(+), 2 deletions(-)
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> >  create mode 100644
> > gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> >
> > diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> > index 3755ec0b8ef..d90be2ec0e8 100644
> > --- a/gcc/config/riscv/riscv-c.cc
> > +++ b/gcc/config/riscv/riscv-c.cc
> > @@ -140,6 +140,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
> >        builtin_define ("__riscv_vector");
> >        builtin_define_with_int_value ("__riscv_v_intrinsic",
> >                                    riscv_ext_version_value (0, 12));
> > +
> > +      if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
> > +     builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
> >      }
> >
> >     if (TARGET_XTHEADVECTOR)
> > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> > index 680c4a728e9..0bc12d4f595 100644
> > --- a/gcc/config/riscv/riscv.cc
> > +++ b/gcc/config/riscv/riscv.cc
> > @@ -535,6 +535,8 @@ static const struct riscv_tune_param
> > optimize_size_tune_info = {
> >  static bool riscv_avoid_shrink_wrapping_separate ();
> >  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int,
> > bool *);
> >  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool
> > *);
> > +static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree,
> > tree, int,
> > +                                                 bool *);
> >
> >  /* Defining target-specific uses of __attribute__.  */
> >  static const attribute_spec riscv_gnu_attributes[] =
> > @@ -557,7 +559,17 @@ static const attribute_spec riscv_gnu_attributes[] =
> >    /* This attribute is used to declare a function, forcing it to use the
> >      standard vector calling convention variant. Syntax:
> >      __attribute__((riscv_vector_cc)). */
> > -  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> > +  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> > +  /* This attribute is used to declare a new type, to appoint the exactly
> > +     bits size of the type.  For example:
> > +
> > +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> > +
> > +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> > +     be used in globals, structs, unions, and arrays instead of sizeless
> > +     types.  */
> > +  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
> > +   riscv_handle_rvv_vector_bits_attribute, NULL},
> >  };
> >
> >  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> > @@ -570,7 +582,17 @@ static const attribute_spec riscv_attributes[] =
> >    /* This attribute is used to declare a function, forcing it to use the
> >       standard vector calling convention variant. Syntax:
> >       [[riscv::vector_cc]]. */
> > -  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> > +  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> > +  /* This attribute is used to declare a new type, to appoint the exactly
> > +     bits size of the type.  For example:
> > +
> > +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> > +
> > +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> > +     be used in globals, structs, unions, and arrays instead of sizeless
> > +     types.  */
> > +  {"rvv_vector_bits", 1, 1, false, true, false, true,
> > +   riscv_handle_rvv_vector_bits_attribute, NULL},
> >  };
> >
> >  static const scoped_attribute_specs riscv_nongnu_attribute_table =
> > @@ -5555,6 +5577,67 @@ riscv_handle_type_attribute (tree *node
> > ATTRIBUTE_UNUSED, tree name, tree args,
> >    return NULL_TREE;
> >  }
> >
> > +static tree
> > +riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree
> > args,
> > +                                     ATTRIBUTE_UNUSED int flags,
> > +                                     bool *no_add_attrs)
> > +{
> > +  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
> > +    return NULL_TREE;
> > +
> > +  *no_add_attrs = true;
> > +
> > +  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
> > +    {
> > +      error (
> > +     "%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
> > +     "riscv_rvv_vector_bits");
> > +      return NULL_TREE;
> > +    }
> > +
> > +  tree type = *node;
> > +
> > +  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
> > +    {
> > +      error ("%qs applied to non-RVV type %qT",
> > "riscv_rvv_vector_bits", type);
> > +      return NULL_TREE;
> > +    }
> > +
> > +  tree size = TREE_VALUE (args);
> > +
> > +  if (TREE_CODE (size) != INTEGER_CST)
> > +    {
> > +      error ("%qs requires an integer constant",
> > "riscv_rvv_vector_bits");
> > +      return NULL_TREE;
> > +    }
> > +
> > +  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
> > +  unsigned HOST_WIDE_INT type_mode_bits
> > +    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
> > +
> > +  if (args_in_bits != type_mode_bits)
> > +    {
> > +      error ("invalid RVV vector size %qd, "
> > +          "expected size is %qd based on LMUL of type and %qs",
> > +          (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
> > +      return NULL_TREE;
> > +    }
> > +
> > +  type = build_distinct_type_copy (type);
> > +  TYPE_ATTRIBUTES (type)
> > +    = remove_attribute ("RVV sizeless type",
> > +                     copy_list (TYPE_ATTRIBUTES (type)));
> > +
> > +  /* The operations like alu/cmp on vbool*_t is not well defined,
> > +     continue to treat vbool*_t as indivisible.  */
> > +  if (!VECTOR_BOOLEAN_TYPE_P (type))
> > +    TYPE_INDIVISIBLE_P (type) = 0;
> > +
> > +  *node = type;
> > +
> > +  return NULL_TREE;
> > +}
> > +
> >  /* Return true if function TYPE is an interrupt function.  */
> >  static bool
> >  riscv_interrupt_type_p (tree type)
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> > new file mode 100644
> > index 00000000000..8b08ba28130
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3"
> > } */
> > +
> > +#include "riscv_vector.h"
> > +
> > +typedef int fixed_vint32m1_t
> > __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error
> > "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> > new file mode 100644
> > index 00000000000..0ff48a29f7e
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> > @@ -0,0 +1,53 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_rvv_vector_bits.h"
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
> > +
> > +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> > new file mode 100644
> > index 00000000000..726c56b4a7e
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> > @@ -0,0 +1,76 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_rvv_vector_bits.h"
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
> > +
> > +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> > new file mode 100644
> > index 00000000000..5c2346dff3e
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> > @@ -0,0 +1,14 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_rvv_vector_bits.h"
> > +
> > +TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
> > +TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
> > +TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
> > +TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
> > +TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
> > +TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
> > +TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
> > +
> > +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> > new file mode 100644
> > index 00000000000..71d8b597da0
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> > @@ -0,0 +1,10 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
> > +
> > +void test () {
> > +
> > +#if defined __riscv_v_fixed_vlen
> > +#error "__riscv_v_fixed_vlen should not be defined"
> > +#endif
> > +
> > +}
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> > new file mode 100644
> > index 00000000000..b60ae4d20ff
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> > @@ -0,0 +1,10 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -mrvv-vector-bits=zvl"
> > } */
> > +
> > +void test () {
> > +
> > +#if __riscv_v_fixed_vlen != 128
> > +#error "__riscv_v_fixed_vlen should be 128"
> > +#endif
> > +
> > +}
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> > new file mode 100644
> > index 00000000000..95edbbbd38d
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> > @@ -0,0 +1,10 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3
> > -mrvv-vector-bits=zvl" } */
> > +
> > +void test () {
> > +
> > +#if __riscv_v_fixed_vlen != 512
> > +#error "__riscv_v_fixed_vlen should be 512"
> > +#endif
> > +
> > +}
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> > new file mode 100644
> > index 00000000000..df73f203791
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> > @@ -0,0 +1,11 @@
> > +
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d
> > -mrvv-vector-bits=scalable -O3" } */
> > +
> > +void test () {
> > +
> > +#if defined __riscv_v_fixed_vlen
> > +#error "__riscv_v_fixed_vlen should not be defined"
> > +#endif
> > +
> > +}
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> > new file mode 100644
> > index 00000000000..fa39a18d47c
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> > @@ -0,0 +1,10 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3
> > -mrvv-vector-bits=zvl" } */
> > +
> > +void test () {
> > +
> > +#if __riscv_v_fixed_vlen != 4096
> > +#error "__riscv_v_fixed_vlen should be 4096"
> > +#endif
> > +
> > +}
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> > new file mode 100644
> > index 00000000000..6b841d7b1d4
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3"
> > } */
> > +
> > +#include "riscv_vector.h"
> > +
> > +typedef vint32m1_t fixed_vint32m1_t
> > __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error
> > "'riscv_rvv_vector_bits' requires an integer constant" } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> > new file mode 100644
> > index 00000000000..e1b0664eacb
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> > +
> > +#include "riscv_vector.h"
> > +
> > +typedef vint32m1_t fixed_vint32m1_t
> > __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error
> > "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl'
> > is specified" } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> > new file mode 100644
> > index 00000000000..eef15654110
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_vector.h"
> > +
> > +typedef vint32m1_t fixed_vint32m1_t
> > __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV
> > vector size '128', expected size is '256' based on LMUL of type and
> > '-mrvv-vector-bits=zvl'" } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> > new file mode 100644
> > index 00000000000..6b4f19cd9f2
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_vector.h"
> > +
> > +typedef vint32m2_t fixed_vint32m2_t
> > __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV
> > vector size '128', expected size is '256' based on LMUL of type and
> > '-mrvv-vector-bits=zvl'" } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> > new file mode 100644
> > index 00000000000..bc346917fe5
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> > @@ -0,0 +1,6 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_vector.h"
> > +
> > +typedef vint32mf2_t fixed_vint32mf2_t
> > __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV
> > vector size '256', expected size is '128' based on LMUL of type and
> > '-mrvv-vector-bits=zvl'" } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> > new file mode 100644
> > index 00000000000..611a4bb88ba
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> > @@ -0,0 +1,76 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_rvv_vector_bits.h"
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
> > +
> > +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> > new file mode 100644
> > index 00000000000..bb8d1da72b2
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> > @@ -0,0 +1,75 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_rvv_vector_bits.h"
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
> > +
> > +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> > new file mode 100644
> > index 00000000000..701f833b41b
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> > @@ -0,0 +1,76 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64
> > -mrvv-vector-bits=zvl -O3" } */
> > +
> > +#include "riscv_rvv_vector_bits.h"
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
> > +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
> > +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
> > +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
> > +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
> > +
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
> > +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
> > +
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
> > +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
> > +
> > +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> > diff --git
> > a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> > b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> > new file mode 100644
> > index 00000000000..a7d68f2c36b
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> > @@ -0,0 +1,108 @@
> > +#ifndef HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> > +#define HAVE_TEST_RISCV_RVV_VECTOR_BITS_H
> > +
> > +#include "riscv_vector.h"
> > +#include "../autovec/vls/def.h"
> > +
> > +#define DEF_FIXED_TYPE(T, N)
> >         \
> > +  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
> > +
> > +#define DEF_FIXED_GLOBAL_VAR(T, N)
> >         \
> > +  fixed_##T global_fixed_##T##_##N##_bits_var;
> > +
> > +#define DEF_FIXED_STRUCT_TYPE(T, N)
> >         \
> > +  struct fixed_##T##_##N##_bits_struct
> >         \
> > +  {
> >         \
> > +    fixed_##T a, b[2];
> >         \
> > +  };
> > +
> > +#define DEF_FIXED_UNION_TYPE(T, N)
> >         \
> > +  union fixed_##T##_##N##_bits_union
> >         \
> > +  {
> >         \
> > +    fixed_##T a, b[3];
> >         \
> > +  };
> > +
> > +#define TEST_FIXED_TYPE_SIZE(T, N)
> >         \
> > +  void test_fixed_##T##_##N##_bits_size ()
> >         \
> > +  {
> >         \
> > +    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),
> >         \
> > +                 "Fixed RVV register types should be equal.");              \
> > +  }
> > +
> > +#define TEST_FIXED_TYPE_CVT(T, N, NEW_TYPE)
> >         \
> > +  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)
> >         \
> > +  {
> >         \
> > +    return (NEW_TYPE) a;
> >         \
> > +  }
> > +
> > +#define TEST_FIXED_BINARY(T, N, OP, NAME)
> >         \
> > +  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,
> >         \
> > +                                                    fixed_##T b)            \
> > +  {
> >         \
> > +    return a OP b;
> >         \
> > +  }
> > +
> > +#define TEST_FIXED_UNARY(T, N, OP, NAME)
> >         \
> > +  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)
> >         \
> > +  {
> >         \
> > +    return OP a;
> >         \
> > +  }
> > +
> > +#define TEST_FIXED_TYPE_CMP(T, N)
> >         \
> > +  TEST_FIXED_BINARY(T, N, ==, eq)
> >         \
> > +  TEST_FIXED_BINARY(T, N, !=, ne)
> >         \
> > +  TEST_FIXED_BINARY(T, N, >,  gt)
> >         \
> > +  TEST_FIXED_BINARY(T, N, <,  lt)
> >         \
> > +  TEST_FIXED_BINARY(T, N, >=, ge)
> >         \
> > +  TEST_FIXED_BINARY(T, N, <=, le)
> > +
> > +#define TEST_FIXED_TYPE_INT_ALU(T, N)
> >         \
> > +  TEST_FIXED_BINARY(T, N, +,  add)
> >         \
> > +  TEST_FIXED_BINARY(T, N, -,  sub)
> >         \
> > +  TEST_FIXED_BINARY(T, N, *,  mul)
> >         \
> > +  TEST_FIXED_BINARY(T, N, /,  div)
> >         \
> > +  TEST_FIXED_BINARY(T, N, %,  mod)
> >         \
> > +  TEST_FIXED_BINARY(T, N, &,  and)
> >         \
> > +  TEST_FIXED_BINARY(T, N, |,  ior)
> >         \
> > +  TEST_FIXED_BINARY(T, N, ^,  xor)
> >         \
> > +  TEST_FIXED_BINARY(T, N, >>, rsh)
> >         \
> > +  TEST_FIXED_BINARY(T, N, <<, lsh)
> >         \
> > +  TEST_FIXED_UNARY(T, N, ~, not)
> >         \
> > +  TEST_FIXED_UNARY(T, N, -, neg)
> > +
> > +#define TEST_FIXED_TYPE_FLOAT_ALU(T, N)
> >         \
> > +  TEST_FIXED_BINARY(T, N, +,  add)
> >         \
> > +  TEST_FIXED_BINARY(T, N, -,  sub)
> >         \
> > +  TEST_FIXED_BINARY(T, N, *,  mul)
> >         \
> > +  TEST_FIXED_BINARY(T, N, /,  div)
> >         \
> > +  TEST_FIXED_UNARY(T, N, -,  neg)
> > +
> > +#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)
> >         \
> > +  DEF_FIXED_TYPE (T, N)
> >         \
> > +  TEST_FIXED_TYPE_SIZE (T, N)
> >         \
> > +  DEF_FIXED_GLOBAL_VAR (T, N)
> >         \
> > +  DEF_FIXED_STRUCT_TYPE (T, N)
> >         \
> > +  DEF_FIXED_UNION_TYPE (T, N)
> >         \
> > +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> >         \
> > +  TEST_FIXED_TYPE_CMP (T, N)
> >         \
> > +  TEST_FIXED_TYPE_INT_ALU (T, N)
> >         \
> > +
> > +#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)
> >         \
> > +  DEF_FIXED_TYPE (T, N)
> >         \
> > +  TEST_FIXED_TYPE_SIZE (T, N)
> >         \
> > +  DEF_FIXED_GLOBAL_VAR (T, N)
> >         \
> > +  DEF_FIXED_STRUCT_TYPE (T, N)
> >         \
> > +  DEF_FIXED_UNION_TYPE (T, N)
> >         \
> > +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> >         \
> > +  TEST_FIXED_TYPE_CMP (T, N)
> >         \
> > +  TEST_FIXED_TYPE_FLOAT_ALU (T, N)
> >         \
> > +
> > +#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)
> >         \
> > +  DEF_FIXED_TYPE (T, N)
> >         \
> > +  TEST_FIXED_TYPE_SIZE (T, N)
> >         \
> > +  DEF_FIXED_GLOBAL_VAR (T, N)
> >         \
> > +  DEF_FIXED_STRUCT_TYPE (T, N)
> >         \
> > +  DEF_FIXED_UNION_TYPE (T, N)
> >         \
> > +  TEST_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> > +
> > +#endif
> > --
> > 2.34.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-21 13:25   ` Kito Cheng
@ 2024-03-21 14:11     ` Li, Pan2
  2024-03-21 14:15       ` Kito Cheng
  0 siblings, 1 reply; 15+ messages in thread
From: Li, Pan2 @ 2024-03-21 14:11 UTC (permalink / raw)
  To: Kito Cheng
  Cc: gcc-patches, juzhe.zhong, Wang, Yanzhang, rdapp.gcc, vineetg, palmer

> The result of comparison should be vbool* rather than v[u]int*.
> The result of comparison should be vbool* rather than vfloat*,
> otherwise all 1 is not really meanful for floating point value.

> But I know clang generates the same strange/wrong code here...

I see, will update the test cases and double check about it in v4.

> &, ^, | has supported on clang, so I think we should support that as well

Looks gcc lack of such operation right now, so mark the TYPE_INDIVISIBLE_P (type) = 0 as aarch64 did.
I have a try but I am afraid we need separated patch to take care of it for risk control consideration.

Pan

-----Original Message-----
From: Kito Cheng <kito.cheng@gmail.com> 
Sent: Thursday, March 21, 2024 9:25 PM
To: Li, Pan2 <pan2.li@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; Wang, Yanzhang <yanzhang.wang@intel.com>; rdapp.gcc@gmail.com; vineetg@rivosinc.com; palmer@rivosinc.com
Subject: Re: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV

> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=

The result of comparison should be vbool* rather than v[u]int*.

> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=

The result of comparison should be vbool* rather than vfloat*,
otherwise all 1 is not really meanful for floating point value.

But I know clang generates the same strange/wrong code here...

> * ALU: +, -, *, /, -
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.

&, ^, | has supported on clang, so I think we should support that as well

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-21 14:11     ` Li, Pan2
@ 2024-03-21 14:15       ` Kito Cheng
  0 siblings, 0 replies; 15+ messages in thread
From: Kito Cheng @ 2024-03-21 14:15 UTC (permalink / raw)
  To: Li, Pan2
  Cc: gcc-patches, juzhe.zhong, Wang, Yanzhang, rdapp.gcc, vineetg, palmer

> > &, ^, | has supported on clang, so I think we should support that as well
>
> Looks gcc lack of such operation right now, so mark the TYPE_INDIVISIBLE_P (type) = 0 as aarch64 did.
> I have a try but I am afraid we need separated patch to take care of it for risk control consideration.

Yeah, agree, that's defer this part to GCC 15 :)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v4] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-06  6:38 [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV pan2.li
                   ` (2 preceding siblings ...)
  2024-03-12  6:15 ` [PATCH v3] " pan2.li
@ 2024-03-22  6:54 ` pan2.li
  2024-03-22 10:05   ` Kito Cheng
  3 siblings, 1 reply; 15+ messages in thread
From: pan2.li @ 2024-03-22  6:54 UTC (permalink / raw)
  To: gcc-patches
  Cc: juzhe.zhong, kito.cheng, yanzhang.wang, rdapp.gcc, vineetg,
	palmer, Pan Li

From: Pan Li <pan2.li@intel.com>

This patch would like to introduce one new gcc attribute for RVV.
This attribute is used to define fixed-length variants of one
existing sizeless RVV types.

This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
one args should be the integer constant and its' value is terminated
by the LMUL and the vector register bits in zvl*b.  For example:

typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));

The above type define is valid when -march=rv64gc_zve64d_zvl64b
(aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
-march=rv64gcv_zvl128b similar to below.

"error: invalid RVV vector size '128', expected size is '256' based on
LMUL of type and '-mrvv-vector-bits=zvl'"

Meanwhile, a pre-define macro __riscv_v_fixed_vlen is introduced to
represent the fixed vlen in a RVV vector register.

For the vint*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -

The CMP will return vint*m*_t the same as aarch64 sve. For example:
typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128)));
fixed_vint32m1_t less_than (fixed_vint32m1_t a, fixed_vint32m1_t b)
{
  return a < b;
}

For the vfloat*m*_t below operations are allowed.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.
* CMP: >, <, ==, !=, <=, >=
* ALU: +, -, *, /, -

The CMP will return vfloat*m*_t the same as aarch64 sve. For example:
typedef vfloat32m1_t fixed_vfloat32m1_t __attribute__((riscv_rvv_vector_bits(128)));
fixed_vfloat32m1_t less_than (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
{
  return a < b;
}

For the vbool*_t types only below operations are allowed except
the CMP and ALU. The CMP and ALU operations on vbool*_t is not
well defined currently.
* The sizeof.
* The global variable(s).
* The element of union and struct.
* The cast to other equalities.

For the vint*x*m*_t tuple types are not suppored in this patch which is
compatible with clang.

This patch passed the below testsuites.
* The riscv fully regression tests.

gcc/ChangeLog:

	* config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add pre-define
	macro __riscv_v_fixed_vlen when zvl.
	* config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
	New static func to take care of the RVV types decorated by
	the attributes.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
	* gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv-c.cc                   |   3 +
 gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
 .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
 .../riscv/rvv/base/riscv_rvv_vector_bits-13.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-14.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-15.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-16.c |  11 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-17.c |  10 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-18.c |  45 ++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
 .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
 21 files changed, 698 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index 7029ba88186..edb866d51e4 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -140,6 +140,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
       builtin_define ("__riscv_vector");
       builtin_define_with_int_value ("__riscv_v_intrinsic",
 				     riscv_ext_version_value (0, 12));
+
+      if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
+	builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
     }
 
   if (TARGET_XTHEADVECTOR)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 02a927f96b4..14f5b634ea1 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -552,6 +552,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
 static bool riscv_avoid_shrink_wrapping_separate ();
 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
+static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
+						    bool *);
 
 /* Defining target-specific uses of __attribute__.  */
 static const attribute_spec riscv_gnu_attributes[] =
@@ -574,7 +576,17 @@ static const attribute_spec riscv_gnu_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
     standard vector calling convention variant. Syntax:
     __attribute__((riscv_vector_cc)). */
-  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_gnu_attribute_table  =
@@ -587,7 +599,17 @@ static const attribute_spec riscv_attributes[] =
   /* This attribute is used to declare a function, forcing it to use the
      standard vector calling convention variant. Syntax:
      [[riscv::vector_cc]]. */
-  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
+  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
+  /* This attribute is used to declare a new type, to appoint the exactly
+     bits size of the type.  For example:
+
+     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
+
+     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
+     be used in globals, structs, unions, and arrays instead of sizeless
+     types.  */
+  {"rvv_vector_bits", 1, 1, false, true, false, true,
+   riscv_handle_rvv_vector_bits_attribute, NULL},
 };
 
 static const scoped_attribute_specs riscv_nongnu_attribute_table =
@@ -5573,6 +5595,67 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
   return NULL_TREE;
 }
 
+static tree
+riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
+					ATTRIBUTE_UNUSED int flags,
+					bool *no_add_attrs)
+{
+  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
+    return NULL_TREE;
+
+  *no_add_attrs = true;
+
+  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
+    {
+      error (
+	"%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
+	"riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  tree type = *node;
+
+  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
+    {
+      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
+      return NULL_TREE;
+    }
+
+  tree size = TREE_VALUE (args);
+
+  if (TREE_CODE (size) != INTEGER_CST)
+    {
+      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
+  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
+  unsigned HOST_WIDE_INT type_mode_bits
+    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
+
+  if (args_in_bits != type_mode_bits)
+    {
+      error ("invalid RVV vector size %qd, "
+	     "expected size is %qd based on LMUL of type and %qs",
+	     (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
+      return NULL_TREE;
+    }
+
+  type = build_distinct_type_copy (type);
+  TYPE_ATTRIBUTES (type)
+    = remove_attribute ("RVV sizeless type",
+			copy_list (TYPE_ATTRIBUTES (type)));
+
+  /* The operations like alu/cmp on vbool*_t is not well defined,
+     continue to treat vbool*_t as indivisible.  */
+  if (!VECTOR_BOOLEAN_TYPE_P (type))
+    TYPE_INDIVISIBLE_P (type) = 0;
+
+  *node = type;
+
+  return NULL_TREE;
+}
+
 /* Return true if function TYPE is an interrupt function.  */
 static bool
 riscv_interrupt_type_p (tree type)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
new file mode 100644
index 00000000000..8b08ba28130
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
new file mode 100644
index 00000000000..0ff48a29f7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
new file mode 100644
index 00000000000..726c56b4a7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
new file mode 100644
index 00000000000..5c2346dff3e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
+TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
new file mode 100644
index 00000000000..71d8b597da0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+void test () {
+
+#if defined __riscv_v_fixed_vlen
+#error "__riscv_v_fixed_vlen should not be defined"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
new file mode 100644
index 00000000000..b60ae4d20ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
+
+void test () {
+
+#if __riscv_v_fixed_vlen != 128
+#error "__riscv_v_fixed_vlen should be 128"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
new file mode 100644
index 00000000000..95edbbbd38d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
+
+void test () {
+
+#if __riscv_v_fixed_vlen != 512
+#error "__riscv_v_fixed_vlen should be 512"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
new file mode 100644
index 00000000000..df73f203791
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
@@ -0,0 +1,11 @@
+
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=scalable -O3" } */
+
+void test () {
+
+#if defined __riscv_v_fixed_vlen
+#error "__riscv_v_fixed_vlen should not be defined"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
new file mode 100644
index 00000000000..fa39a18d47c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
+
+void test () {
+
+#if __riscv_v_fixed_vlen != 4096
+#error "__riscv_v_fixed_vlen should be 4096"
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
new file mode 100644
index 00000000000..a7530e27d8f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+DEF_FIXED_TYPE (vint32m1_t, 256)
+DEF_FIXED_TYPE (vfloat32m1_t, 256)
+DEF_FIXED_TYPE (vbool1_t, 256)
+DEF_FIXED_TYPE (vbool2_t, 128)
+
+fixed_vint32m1_t
+test_1 (fixed_vint32m1_t a, fixed_vint32m1_t b)
+{
+  return a == b;
+}
+
+fixed_vbool1_t
+test_2 (fixed_vint32m1_t a, fixed_vint32m1_t b)
+{
+  return a == b;
+}
+
+fixed_vfloat32m1_t
+test_3 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
+{
+  return a == b;
+}
+
+fixed_vbool1_t
+test_4 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
+{
+  return a == b;
+}
+
+fixed_vbool2_t
+test_5 (fixed_vint32m1_t a, fixed_vint32m1_t b)
+{
+  return a == b; /* { dg-error {incompatible types when returning type '__vector\(8\) int' but 'fixed_vbool2_t' {aka 'vbool2_t'} was expected} } */
+}
+
+fixed_vbool2_t
+test_6 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
+{
+  return a == b; /* { dg-error {incompatible types when returning type '__vector\(8\) int' but 'fixed_vbool2_t' {aka 'vbool2_t'} was expected} } */
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
new file mode 100644
index 00000000000..6b841d7b1d4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
new file mode 100644
index 00000000000..e1b0664eacb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
new file mode 100644
index 00000000000..eef15654110
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
new file mode 100644
index 00000000000..6b4f19cd9f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
new file mode 100644
index 00000000000..bc346917fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
new file mode 100644
index 00000000000..611a4bb88ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
new file mode 100644
index 00000000000..bb8d1da72b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
new file mode 100644
index 00000000000..701f833b41b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
@@ -0,0 +1,76 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_rvv_vector_bits.h"
+
+TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
+TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
+TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
+
+TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
+TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
+TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
+
+TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
+TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
+TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
+TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
+TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
+
+TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
+TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
+TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
+TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
+
+TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
+TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
+TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
+TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
+
+TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
+TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
+
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
+TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
+
+/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
new file mode 100644
index 00000000000..fd2d352d3e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
@@ -0,0 +1,108 @@
+#ifndef HAVE_DEF_RISCV_RVV_VECTOR_BITS_H
+#define HAVE_DEF_RISCV_RVV_VECTOR_BITS_H
+
+#include "riscv_vector.h"
+#include "../autovec/vls/def.h"
+
+#define DEF_FIXED_TYPE(T, N)                                                   \
+  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
+
+#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
+  fixed_##T global_fixed_##T##_##N##_bits_var;
+
+#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
+  struct fixed_##T##_##N##_bits_struct                                         \
+  {                                                                            \
+    fixed_##T a, b[2];                                                         \
+  };
+
+#define DEF_FIXED_UNION_TYPE(T, N)                                             \
+  union fixed_##T##_##N##_bits_union                                           \
+  {                                                                            \
+    fixed_##T a, b[3];                                                         \
+  };
+
+#define DEF_FIXED_TYPE_SIZE(T, N)                                              \
+  void test_fixed_##T##_##N##_bits_size ()                                     \
+  {                                                                            \
+    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
+		    "Fixed RVV register types should be equal.");              \
+  }
+
+#define DEF_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                     \
+  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
+  {                                                                            \
+    return (NEW_TYPE) a;                                                       \
+  }
+
+#define DEF_FIXED_BINARY(T, N, OP, NAME)                                       \
+  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
+						       fixed_##T b)            \
+  {                                                                            \
+    return a OP b;                                                             \
+  }
+
+#define DEF_FIXED_UNARY(T, N, OP, NAME)                                        \
+  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
+  {                                                                            \
+    return OP a;                                                               \
+  }
+
+#define DEF_FIXED_TYPE_CMP(T, N)                                               \
+  DEF_FIXED_BINARY(T, N, ==, eq)                                               \
+  DEF_FIXED_BINARY(T, N, !=, ne)                                               \
+  DEF_FIXED_BINARY(T, N, >,  gt)                                               \
+  DEF_FIXED_BINARY(T, N, <,  lt)                                               \
+  DEF_FIXED_BINARY(T, N, >=, ge)                                               \
+  DEF_FIXED_BINARY(T, N, <=, le)
+
+#define DEF_FIXED_TYPE_INT_ALU(T, N)                                           \
+  DEF_FIXED_BINARY(T, N, +,  add)                                              \
+  DEF_FIXED_BINARY(T, N, -,  sub)                                              \
+  DEF_FIXED_BINARY(T, N, *,  mul)                                              \
+  DEF_FIXED_BINARY(T, N, /,  div)                                              \
+  DEF_FIXED_BINARY(T, N, %,  mod)                                              \
+  DEF_FIXED_BINARY(T, N, &,  and)                                              \
+  DEF_FIXED_BINARY(T, N, |,  ior)                                              \
+  DEF_FIXED_BINARY(T, N, ^,  xor)                                              \
+  DEF_FIXED_BINARY(T, N, >>, rsh)                                              \
+  DEF_FIXED_BINARY(T, N, <<, lsh)                                              \
+  DEF_FIXED_UNARY(T, N, ~, not)                                                \
+  DEF_FIXED_UNARY(T, N, -, neg)
+
+#define DEF_FIXED_TYPE_FLOAT_ALU(T, N)                                         \
+  DEF_FIXED_BINARY(T, N, +,  add)                                              \
+  DEF_FIXED_BINARY(T, N, -,  sub)                                              \
+  DEF_FIXED_BINARY(T, N, *,  mul)                                              \
+  DEF_FIXED_BINARY(T, N, /,  div)                                              \
+  DEF_FIXED_UNARY(T, N, -,  neg)
+
+#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                          \
+  DEF_FIXED_TYPE_CMP (T, N)                                                    \
+  DEF_FIXED_TYPE_INT_ALU (T, N)                                                \
+
+#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                          \
+  DEF_FIXED_TYPE_CMP (T, N)                                                    \
+  DEF_FIXED_TYPE_FLOAT_ALU (T, N)                                              \
+
+#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
+  DEF_FIXED_TYPE (T, N)                                                        \
+  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
+  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
+  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
+  DEF_FIXED_UNION_TYPE (T, N)                                                  \
+  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)
+
+#endif
-- 
2.34.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v4] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-22  6:54 ` [PATCH v4] " pan2.li
@ 2024-03-22 10:05   ` Kito Cheng
  2024-03-22 10:39     ` Li, Pan2
  0 siblings, 1 reply; 15+ messages in thread
From: Kito Cheng @ 2024-03-22 10:05 UTC (permalink / raw)
  To: pan2.li
  Cc: gcc-patches, juzhe.zhong, yanzhang.wang, rdapp.gcc, vineetg, palmer

LGTM, thanks :)

On Fri, Mar 22, 2024 at 2:55 PM <pan2.li@intel.com> wrote:
>
> From: Pan Li <pan2.li@intel.com>
>
> This patch would like to introduce one new gcc attribute for RVV.
> This attribute is used to define fixed-length variants of one
> existing sizeless RVV types.
>
> This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
> one args should be the integer constant and its' value is terminated
> by the LMUL and the vector register bits in zvl*b.  For example:
>
> typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
>
> The above type define is valid when -march=rv64gc_zve64d_zvl64b
> (aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
> -march=rv64gcv_zvl128b similar to below.
>
> "error: invalid RVV vector size '128', expected size is '256' based on
> LMUL of type and '-mrvv-vector-bits=zvl'"
>
> Meanwhile, a pre-define macro __riscv_v_fixed_vlen is introduced to
> represent the fixed vlen in a RVV vector register.
>
> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> The CMP will return vint*m*_t the same as aarch64 sve. For example:
> typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128)));
> fixed_vint32m1_t less_than (fixed_vint32m1_t a, fixed_vint32m1_t b)
> {
>   return a < b;
> }
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, -
>
> The CMP will return vfloat*m*_t the same as aarch64 sve. For example:
> typedef vfloat32m1_t fixed_vfloat32m1_t __attribute__((riscv_rvv_vector_bits(128)));
> fixed_vfloat32m1_t less_than (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> {
>   return a < b;
> }
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
>
> For the vint*x*m*_t tuple types are not suppored in this patch which is
> compatible with clang.
>
> This patch passed the below testsuites.
> * The riscv fully regression tests.
>
> gcc/ChangeLog:
>
>         * config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add pre-define
>         macro __riscv_v_fixed_vlen when zvl.
>         * config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
>         New static func to take care of the RVV types decorated by
>         the attributes.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-c.cc                   |   3 +
>  gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
>  .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-13.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-14.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-15.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-16.c |  11 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-17.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-18.c |  45 ++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
>  21 files changed, 698 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
>
> diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> index 7029ba88186..edb866d51e4 100644
> --- a/gcc/config/riscv/riscv-c.cc
> +++ b/gcc/config/riscv/riscv-c.cc
> @@ -140,6 +140,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
>        builtin_define ("__riscv_vector");
>        builtin_define_with_int_value ("__riscv_v_intrinsic",
>                                      riscv_ext_version_value (0, 12));
> +
> +      if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
> +       builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
>      }
>
>    if (TARGET_XTHEADVECTOR)
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 02a927f96b4..14f5b634ea1 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -552,6 +552,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
>  static bool riscv_avoid_shrink_wrapping_separate ();
>  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
>  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
> +static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
> +                                                   bool *);
>
>  /* Defining target-specific uses of __attribute__.  */
>  static const attribute_spec riscv_gnu_attributes[] =
> @@ -574,7 +576,17 @@ static const attribute_spec riscv_gnu_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>      standard vector calling convention variant. Syntax:
>      __attribute__((riscv_vector_cc)). */
> -  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>
>  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -587,7 +599,17 @@ static const attribute_spec riscv_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>       standard vector calling convention variant. Syntax:
>       [[riscv::vector_cc]]. */
> -  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>
>  static const scoped_attribute_specs riscv_nongnu_attribute_table =
> @@ -5573,6 +5595,67 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
>    return NULL_TREE;
>  }
>
> +static tree
> +riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
> +                                       ATTRIBUTE_UNUSED int flags,
> +                                       bool *no_add_attrs)
> +{
> +  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
> +    return NULL_TREE;
> +
> +  *no_add_attrs = true;
> +
> +  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
> +    {
> +      error (
> +       "%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
> +       "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  tree type = *node;
> +
> +  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
> +    {
> +      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
> +      return NULL_TREE;
> +    }
> +
> +  tree size = TREE_VALUE (args);
> +
> +  if (TREE_CODE (size) != INTEGER_CST)
> +    {
> +      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
> +  unsigned HOST_WIDE_INT type_mode_bits
> +    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
> +
> +  if (args_in_bits != type_mode_bits)
> +    {
> +      error ("invalid RVV vector size %qd, "
> +            "expected size is %qd based on LMUL of type and %qs",
> +            (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
> +      return NULL_TREE;
> +    }
> +
> +  type = build_distinct_type_copy (type);
> +  TYPE_ATTRIBUTES (type)
> +    = remove_attribute ("RVV sizeless type",
> +                       copy_list (TYPE_ATTRIBUTES (type)));
> +
> +  /* The operations like alu/cmp on vbool*_t is not well defined,
> +     continue to treat vbool*_t as indivisible.  */
> +  if (!VECTOR_BOOLEAN_TYPE_P (type))
> +    TYPE_INDIVISIBLE_P (type) = 0;
> +
> +  *node = type;
> +
> +  return NULL_TREE;
> +}
> +
>  /* Return true if function TYPE is an interrupt function.  */
>  static bool
>  riscv_interrupt_type_p (tree type)
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> new file mode 100644
> index 00000000000..8b08ba28130
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> new file mode 100644
> index 00000000000..0ff48a29f7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> new file mode 100644
> index 00000000000..726c56b4a7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> new file mode 100644
> index 00000000000..5c2346dff3e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> new file mode 100644
> index 00000000000..71d8b597da0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> new file mode 100644
> index 00000000000..b60ae4d20ff
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 128
> +#error "__riscv_v_fixed_vlen should be 128"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> new file mode 100644
> index 00000000000..95edbbbd38d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 512
> +#error "__riscv_v_fixed_vlen should be 512"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> new file mode 100644
> index 00000000000..df73f203791
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> @@ -0,0 +1,11 @@
> +
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=scalable -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> new file mode 100644
> index 00000000000..fa39a18d47c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 4096
> +#error "__riscv_v_fixed_vlen should be 4096"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
> new file mode 100644
> index 00000000000..a7530e27d8f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
> @@ -0,0 +1,45 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +DEF_FIXED_TYPE (vint32m1_t, 256)
> +DEF_FIXED_TYPE (vfloat32m1_t, 256)
> +DEF_FIXED_TYPE (vbool1_t, 256)
> +DEF_FIXED_TYPE (vbool2_t, 128)
> +
> +fixed_vint32m1_t
> +test_1 (fixed_vint32m1_t a, fixed_vint32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vbool1_t
> +test_2 (fixed_vint32m1_t a, fixed_vint32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vfloat32m1_t
> +test_3 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vbool1_t
> +test_4 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vbool2_t
> +test_5 (fixed_vint32m1_t a, fixed_vint32m1_t b)
> +{
> +  return a == b; /* { dg-error {incompatible types when returning type '__vector\(8\) int' but 'fixed_vbool2_t' {aka 'vbool2_t'} was expected} } */
> +}
> +
> +fixed_vbool2_t
> +test_6 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> +{
> +  return a == b; /* { dg-error {incompatible types when returning type '__vector\(8\) int' but 'fixed_vbool2_t' {aka 'vbool2_t'} was expected} } */
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> new file mode 100644
> index 00000000000..6b841d7b1d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> new file mode 100644
> index 00000000000..e1b0664eacb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> new file mode 100644
> index 00000000000..eef15654110
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> new file mode 100644
> index 00000000000..6b4f19cd9f2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> new file mode 100644
> index 00000000000..bc346917fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> new file mode 100644
> index 00000000000..611a4bb88ba
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> new file mode 100644
> index 00000000000..bb8d1da72b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> new file mode 100644
> index 00000000000..701f833b41b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> new file mode 100644
> index 00000000000..fd2d352d3e1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> @@ -0,0 +1,108 @@
> +#ifndef HAVE_DEF_RISCV_RVV_VECTOR_BITS_H
> +#define HAVE_DEF_RISCV_RVV_VECTOR_BITS_H
> +
> +#include "riscv_vector.h"
> +#include "../autovec/vls/def.h"
> +
> +#define DEF_FIXED_TYPE(T, N)                                                   \
> +  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
> +
> +#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
> +  fixed_##T global_fixed_##T##_##N##_bits_var;
> +
> +#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
> +  struct fixed_##T##_##N##_bits_struct                                         \
> +  {                                                                            \
> +    fixed_##T a, b[2];                                                         \
> +  };
> +
> +#define DEF_FIXED_UNION_TYPE(T, N)                                             \
> +  union fixed_##T##_##N##_bits_union                                           \
> +  {                                                                            \
> +    fixed_##T a, b[3];                                                         \
> +  };
> +
> +#define DEF_FIXED_TYPE_SIZE(T, N)                                              \
> +  void test_fixed_##T##_##N##_bits_size ()                                     \
> +  {                                                                            \
> +    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
> +                   "Fixed RVV register types should be equal.");              \
> +  }
> +
> +#define DEF_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                     \
> +  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
> +  {                                                                            \
> +    return (NEW_TYPE) a;                                                       \
> +  }
> +
> +#define DEF_FIXED_BINARY(T, N, OP, NAME)                                       \
> +  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
> +                                                      fixed_##T b)            \
> +  {                                                                            \
> +    return a OP b;                                                             \
> +  }
> +
> +#define DEF_FIXED_UNARY(T, N, OP, NAME)                                        \
> +  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
> +  {                                                                            \
> +    return OP a;                                                               \
> +  }
> +
> +#define DEF_FIXED_TYPE_CMP(T, N)                                               \
> +  DEF_FIXED_BINARY(T, N, ==, eq)                                               \
> +  DEF_FIXED_BINARY(T, N, !=, ne)                                               \
> +  DEF_FIXED_BINARY(T, N, >,  gt)                                               \
> +  DEF_FIXED_BINARY(T, N, <,  lt)                                               \
> +  DEF_FIXED_BINARY(T, N, >=, ge)                                               \
> +  DEF_FIXED_BINARY(T, N, <=, le)
> +
> +#define DEF_FIXED_TYPE_INT_ALU(T, N)                                           \
> +  DEF_FIXED_BINARY(T, N, +,  add)                                              \
> +  DEF_FIXED_BINARY(T, N, -,  sub)                                              \
> +  DEF_FIXED_BINARY(T, N, *,  mul)                                              \
> +  DEF_FIXED_BINARY(T, N, /,  div)                                              \
> +  DEF_FIXED_BINARY(T, N, %,  mod)                                              \
> +  DEF_FIXED_BINARY(T, N, &,  and)                                              \
> +  DEF_FIXED_BINARY(T, N, |,  ior)                                              \
> +  DEF_FIXED_BINARY(T, N, ^,  xor)                                              \
> +  DEF_FIXED_BINARY(T, N, >>, rsh)                                              \
> +  DEF_FIXED_BINARY(T, N, <<, lsh)                                              \
> +  DEF_FIXED_UNARY(T, N, ~, not)                                                \
> +  DEF_FIXED_UNARY(T, N, -, neg)
> +
> +#define DEF_FIXED_TYPE_FLOAT_ALU(T, N)                                         \
> +  DEF_FIXED_BINARY(T, N, +,  add)                                              \
> +  DEF_FIXED_BINARY(T, N, -,  sub)                                              \
> +  DEF_FIXED_BINARY(T, N, *,  mul)                                              \
> +  DEF_FIXED_BINARY(T, N, /,  div)                                              \
> +  DEF_FIXED_UNARY(T, N, -,  neg)
> +
> +#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                          \
> +  DEF_FIXED_TYPE_CMP (T, N)                                                    \
> +  DEF_FIXED_TYPE_INT_ALU (T, N)                                                \
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                          \
> +  DEF_FIXED_TYPE_CMP (T, N)                                                    \
> +  DEF_FIXED_TYPE_FLOAT_ALU (T, N)                                              \
> +
> +#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> +
> +#endif
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: [PATCH v4] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV
  2024-03-22 10:05   ` Kito Cheng
@ 2024-03-22 10:39     ` Li, Pan2
  0 siblings, 0 replies; 15+ messages in thread
From: Li, Pan2 @ 2024-03-22 10:39 UTC (permalink / raw)
  To: Kito Cheng
  Cc: gcc-patches, juzhe.zhong, Wang, Yanzhang, rdapp.gcc, vineetg, palmer

Committed, thanks Kito.

Pan

-----Original Message-----
From: Kito Cheng <kito.cheng@gmail.com> 
Sent: Friday, March 22, 2024 6:06 PM
To: Li, Pan2 <pan2.li@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; Wang, Yanzhang <yanzhang.wang@intel.com>; rdapp.gcc@gmail.com; vineetg@rivosinc.com; palmer@rivosinc.com
Subject: Re: [PATCH v4] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV

LGTM, thanks :)

On Fri, Mar 22, 2024 at 2:55 PM <pan2.li@intel.com> wrote:
>
> From: Pan Li <pan2.li@intel.com>
>
> This patch would like to introduce one new gcc attribute for RVV.
> This attribute is used to define fixed-length variants of one
> existing sizeless RVV types.
>
> This attribute is valid if and only if the mrvv-vector-bits=zvl, the only
> one args should be the integer constant and its' value is terminated
> by the LMUL and the vector register bits in zvl*b.  For example:
>
> typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128)));
>
> The above type define is valid when -march=rv64gc_zve64d_zvl64b
> (aka 2(m2) * 64 = 128 for vin32m2_t), and will report error when
> -march=rv64gcv_zvl128b similar to below.
>
> "error: invalid RVV vector size '128', expected size is '256' based on
> LMUL of type and '-mrvv-vector-bits=zvl'"
>
> Meanwhile, a pre-define macro __riscv_v_fixed_vlen is introduced to
> represent the fixed vlen in a RVV vector register.
>
> For the vint*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, %, &, |, ^, >>, <<, ~, -
>
> The CMP will return vint*m*_t the same as aarch64 sve. For example:
> typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128)));
> fixed_vint32m1_t less_than (fixed_vint32m1_t a, fixed_vint32m1_t b)
> {
>   return a < b;
> }
>
> For the vfloat*m*_t below operations are allowed.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
> * CMP: >, <, ==, !=, <=, >=
> * ALU: +, -, *, /, -
>
> The CMP will return vfloat*m*_t the same as aarch64 sve. For example:
> typedef vfloat32m1_t fixed_vfloat32m1_t __attribute__((riscv_rvv_vector_bits(128)));
> fixed_vfloat32m1_t less_than (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> {
>   return a < b;
> }
>
> For the vbool*_t types only below operations are allowed except
> the CMP and ALU. The CMP and ALU operations on vbool*_t is not
> well defined currently.
> * The sizeof.
> * The global variable(s).
> * The element of union and struct.
> * The cast to other equalities.
>
> For the vint*x*m*_t tuple types are not suppored in this patch which is
> compatible with clang.
>
> This patch passed the below testsuites.
> * The riscv fully regression tests.
>
> gcc/ChangeLog:
>
>         * config/riscv/riscv-c.cc (riscv_cpu_cpp_builtins): Add pre-define
>         macro __riscv_v_fixed_vlen when zvl.
>         * config/riscv/riscv.cc (riscv_handle_rvv_vector_bits_attribute):
>         New static func to take care of the RVV types decorated by
>         the attributes.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c: New test.
>         * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-c.cc                   |   3 +
>  gcc/config/riscv/riscv.cc                     |  87 +++++++++++++-
>  .../riscv/rvv/base/riscv_rvv_vector_bits-1.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-10.c |  53 +++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-11.c |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-12.c |  14 +++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-13.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-14.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-15.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-16.c |  11 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-17.c |  10 ++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-18.c |  45 ++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-2.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   6 +
>  .../riscv/rvv/base/riscv_rvv_vector_bits-7.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-8.c  |  75 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits-9.c  |  76 ++++++++++++
>  .../riscv/rvv/base/riscv_rvv_vector_bits.h    | 108 ++++++++++++++++++
>  21 files changed, 698 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
>
> diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
> index 7029ba88186..edb866d51e4 100644
> --- a/gcc/config/riscv/riscv-c.cc
> +++ b/gcc/config/riscv/riscv-c.cc
> @@ -140,6 +140,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile)
>        builtin_define ("__riscv_vector");
>        builtin_define_with_int_value ("__riscv_v_intrinsic",
>                                      riscv_ext_version_value (0, 12));
> +
> +      if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
> +       builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
>      }
>
>    if (TARGET_XTHEADVECTOR)
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 02a927f96b4..14f5b634ea1 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -552,6 +552,8 @@ static const struct riscv_tune_param optimize_size_tune_info = {
>  static bool riscv_avoid_shrink_wrapping_separate ();
>  static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
>  static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
> +static tree riscv_handle_rvv_vector_bits_attribute (tree *, tree, tree, int,
> +                                                   bool *);
>
>  /* Defining target-specific uses of __attribute__.  */
>  static const attribute_spec riscv_gnu_attributes[] =
> @@ -574,7 +576,17 @@ static const attribute_spec riscv_gnu_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>      standard vector calling convention variant. Syntax:
>      __attribute__((riscv_vector_cc)). */
> -  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"riscv_vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"riscv_rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>
>  static const scoped_attribute_specs riscv_gnu_attribute_table  =
> @@ -587,7 +599,17 @@ static const attribute_spec riscv_attributes[] =
>    /* This attribute is used to declare a function, forcing it to use the
>       standard vector calling convention variant. Syntax:
>       [[riscv::vector_cc]]. */
> -  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL}
> +  {"vector_cc", 0, 0, false, true, true, true, NULL, NULL},
> +  /* This attribute is used to declare a new type, to appoint the exactly
> +     bits size of the type.  For example:
> +
> +     typedef vint8m1_t f_vint8m1_t __attribute__((riscv_rvv_vector_bits(256)));
> +
> +     The new created type f_vint8m1_t will be exactly 256 bits.  It can be
> +     be used in globals, structs, unions, and arrays instead of sizeless
> +     types.  */
> +  {"rvv_vector_bits", 1, 1, false, true, false, true,
> +   riscv_handle_rvv_vector_bits_attribute, NULL},
>  };
>
>  static const scoped_attribute_specs riscv_nongnu_attribute_table =
> @@ -5573,6 +5595,67 @@ riscv_handle_type_attribute (tree *node ATTRIBUTE_UNUSED, tree name, tree args,
>    return NULL_TREE;
>  }
>
> +static tree
> +riscv_handle_rvv_vector_bits_attribute (tree *node, tree name, tree args,
> +                                       ATTRIBUTE_UNUSED int flags,
> +                                       bool *no_add_attrs)
> +{
> +  if (!is_attribute_p ("riscv_rvv_vector_bits", name))
> +    return NULL_TREE;
> +
> +  *no_add_attrs = true;
> +
> +  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
> +    {
> +      error (
> +       "%qs is only supported when %<-mrvv-vector-bits=zvl%> is specified",
> +       "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  tree type = *node;
> +
> +  if (!VECTOR_TYPE_P (type) || !riscv_vector::builtin_type_p (type))
> +    {
> +      error ("%qs applied to non-RVV type %qT", "riscv_rvv_vector_bits", type);
> +      return NULL_TREE;
> +    }
> +
> +  tree size = TREE_VALUE (args);
> +
> +  if (TREE_CODE (size) != INTEGER_CST)
> +    {
> +      error ("%qs requires an integer constant", "riscv_rvv_vector_bits");
> +      return NULL_TREE;
> +    }
> +
> +  unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
> +  unsigned HOST_WIDE_INT type_mode_bits
> +    = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
> +
> +  if (args_in_bits != type_mode_bits)
> +    {
> +      error ("invalid RVV vector size %qd, "
> +            "expected size is %qd based on LMUL of type and %qs",
> +            (int)args_in_bits, (int)type_mode_bits, "-mrvv-vector-bits=zvl");
> +      return NULL_TREE;
> +    }
> +
> +  type = build_distinct_type_copy (type);
> +  TYPE_ATTRIBUTES (type)
> +    = remove_attribute ("RVV sizeless type",
> +                       copy_list (TYPE_ATTRIBUTES (type)));
> +
> +  /* The operations like alu/cmp on vbool*_t is not well defined,
> +     continue to treat vbool*_t as indivisible.  */
> +  if (!VECTOR_BOOLEAN_TYPE_P (type))
> +    TYPE_INDIVISIBLE_P (type) = 0;
> +
> +  *node = type;
> +
> +  return NULL_TREE;
> +}
> +
>  /* Return true if function TYPE is an interrupt function.  */
>  static bool
>  riscv_interrupt_type_p (tree type)
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> new file mode 100644
> index 00000000000..8b08ba28130
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-1.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef int fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' applied to non-RVV type 'int'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> new file mode 100644
> index 00000000000..0ff48a29f7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-10.c
> @@ -0,0 +1,53 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve32f_zvl32b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 256, v32qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  256, v16hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  32, v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  64, v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 128, v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 256, v8si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 256, v32uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  256, v16uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  32, v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  64, v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 128, v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 256, v8usi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  256, v16hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  32, v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  64, v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 128, v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 256, v8sf)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> new file mode 100644
> index 00000000000..726c56b4a7e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-11.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  512,   v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 1024,  v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 2048,  v256qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  4096,  v512qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  8192, v1024qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 16384, v2048qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 32768, v4096qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t, 1024,   v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 2048,  v128hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  4096,  v256hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  8192,  v512hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 16384, v1024hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 32768, v2048hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 2048,   v64si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  4096,  v128si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  8192,  v256si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 16384,  v512si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 32768, v1024si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  4096,  v64di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  8192, v128di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 16384, v256di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 32768, v512di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  512,   v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 1024,  v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 2048,  v256uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  4096,  v512uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  8192, v1024uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 16384, v2048uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 32768, v4096uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t, 1024,   v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 2048,  v128uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  4096,  v256uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  8192,  v512uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 16384, v1024uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 32768, v2048uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 2048,   v64usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  4096,  v128usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  8192,  v256usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 16384,  v512usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 32768, v1024usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  4096,  v64udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  8192, v128udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 16384, v256udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 32768, v512udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t, 1024,   v64hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 2048,  v128hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  4096,  v256hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  8192,  v512hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 16384, v1024hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 32768, v2048hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 2048,   v64sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  4096,  v128sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  8192,  v256sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 16384,  v512sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 32768, v1024sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  4096,  v64df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  8192, v128df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 16384, v256df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 32768, v512df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> new file mode 100644
> index 00000000000..5c2346dff3e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-12.c
> @@ -0,0 +1,14 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_BOOL_ALL (vbool1_t, 128, v16qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool2_t,  64,  v8qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool4_t,  32,  v4qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool8_t,  16,  v2qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool16_t,  8,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool32_t,  4,  v1qi)
> +TEST_FIXED_TYPE_BOOL_ALL (vbool64_t,  2,  v1qi)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> new file mode 100644
> index 00000000000..71d8b597da0
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-13.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> new file mode 100644
> index 00000000000..b60ae4d20ff
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-14.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 128
> +#error "__riscv_v_fixed_vlen should be 128"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> new file mode 100644
> index 00000000000..95edbbbd38d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-15.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 512
> +#error "__riscv_v_fixed_vlen should be 512"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> new file mode 100644
> index 00000000000..df73f203791
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-16.c
> @@ -0,0 +1,11 @@
> +
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-vector-bits=scalable -O3" } */
> +
> +void test () {
> +
> +#if defined __riscv_v_fixed_vlen
> +#error "__riscv_v_fixed_vlen should not be defined"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> new file mode 100644
> index 00000000000..fa39a18d47c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-17.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl4096b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +void test () {
> +
> +#if __riscv_v_fixed_vlen != 4096
> +#error "__riscv_v_fixed_vlen should be 4096"
> +#endif
> +
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
> new file mode 100644
> index 00000000000..a7530e27d8f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-18.c
> @@ -0,0 +1,45 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -mrvv-vector-bits=zvl" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +DEF_FIXED_TYPE (vint32m1_t, 256)
> +DEF_FIXED_TYPE (vfloat32m1_t, 256)
> +DEF_FIXED_TYPE (vbool1_t, 256)
> +DEF_FIXED_TYPE (vbool2_t, 128)
> +
> +fixed_vint32m1_t
> +test_1 (fixed_vint32m1_t a, fixed_vint32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vbool1_t
> +test_2 (fixed_vint32m1_t a, fixed_vint32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vfloat32m1_t
> +test_3 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vbool1_t
> +test_4 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> +{
> +  return a == b;
> +}
> +
> +fixed_vbool2_t
> +test_5 (fixed_vint32m1_t a, fixed_vint32m1_t b)
> +{
> +  return a == b; /* { dg-error {incompatible types when returning type '__vector\(8\) int' but 'fixed_vbool2_t' {aka 'vbool2_t'} was expected} } */
> +}
> +
> +fixed_vbool2_t
> +test_6 (fixed_vfloat32m1_t a, fixed_vfloat32m1_t b)
> +{
> +  return a == b; /* { dg-error {incompatible types when returning type '__vector\(8\) int' but 'fixed_vbool2_t' {aka 'vbool2_t'} was expected} } */
> +}
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> new file mode 100644
> index 00000000000..6b841d7b1d4
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-2.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits("123"))); /* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> new file mode 100644
> index 00000000000..e1b0664eacb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "'riscv_rvv_vector_bits' is only supported when '-mrvv-vector-bits=zvl' is specified" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> new file mode 100644
> index 00000000000..eef15654110
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m1_t fixed_vint32m1_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> new file mode 100644
> index 00000000000..6b4f19cd9f2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32m2_t fixed_vint32m2_t __attribute__((riscv_rvv_vector_bits(128))); /* { dg-error "invalid RVV vector size '128', expected size is '256' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> new file mode 100644
> index 00000000000..bc346917fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c
> @@ -0,0 +1,6 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +typedef vint32mf2_t fixed_vint32mf2_t __attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector size '256', expected size is '128' based on LMUL of type and '-mrvv-vector-bits=zvl'" } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> new file mode 100644
> index 00000000000..611a4bb88ba
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-7.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl128b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  16,   v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 1024, v128qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  512, v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 1024, v64hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 1024, v32si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  128,  v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 1024, v16di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  16,   v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  32,   v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 1024, v128uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  512, v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 1024, v64uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 1024, v32usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  128,  v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 1024, v16udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  512, v32hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 1024, v64hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t,  512, v16sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 1024, v32sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  128,  v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  256,  v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t,  512,  v8df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 1024, v16df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> new file mode 100644
> index 00000000000..bb8d1da72b2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-8.c
> @@ -0,0 +1,75 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv_zvl256b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  32,   v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t,  64,   v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 128,  v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  256,  v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t,  512,  v64qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 1024, v128qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 2048, v256qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 2048, v32di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t,  64,   v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 128,  v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  256,  v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t,  512,  v64uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 1024, v128uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 2048, v256uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  64,   v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t, 128,   v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,  256,  v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  512,  v32uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t, 1024,  v64uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t, 2048, v128uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t,  512, v16usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 1024, v32usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 2048, v64usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  256,  v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t,  512,  v8udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 1024, v16udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 2048, v32udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  64,   v4hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t, 128,   v8hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,  256,  v16hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  512,  v32hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t, 1024,  v64hi)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t, 2048, v128hi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 128,  v4si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  256,  v8si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t,  512, v16si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 1024, v32si)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 2048, v64si)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  256,  v4di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t,  512,  v8di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 1024, v16di)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 2048, v32di)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> new file mode 100644
> index 00000000000..701f833b41b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-9.c
> @@ -0,0 +1,76 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zve64d_zvl64b_zfh_zvfh -mabi=lp64 -mrvv-vector-bits=zvl -O3" } */
> +
> +#include "riscv_rvv_vector_bits.h"
> +
> +TEST_FIXED_TYPE_INT_ALL (vint8mf8_t,  8,  v1qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf4_t, 16,  v2qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8mf2_t, 32,  v4qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m1_t,  64,  v8qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m2_t, 128, v16qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m4_t, 256, v32qi)
> +TEST_FIXED_TYPE_INT_ALL (vint8m8_t, 512, v64qi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint16mf4_t,  16,  v1hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16mf2_t,  32,  v2hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m1_t,   64,  v4hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m2_t,  128,  v8hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m4_t,  256, v16hi)
> +TEST_FIXED_TYPE_INT_ALL (vint16m8_t,  512, v32hi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint32mf2_t, 32,  v1si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m1_t,  64,  v2si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m2_t, 128,  v4si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m4_t, 256,  v8si)
> +TEST_FIXED_TYPE_INT_ALL (vint32m8_t, 512, v16si)
> +
> +TEST_FIXED_TYPE_INT_ALL (vint64m1_t,  64, v1di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m2_t, 128, v2di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m4_t, 256, v4di)
> +TEST_FIXED_TYPE_INT_ALL (vint64m8_t, 512, v8di)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf8_t,  8,  v1uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf4_t, 16,  v2uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8mf2_t, 32,  v4uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m1_t,  64,  v8uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m2_t, 128, v16uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m4_t, 256, v32uqi)
> +TEST_FIXED_TYPE_INT_ALL (vuint8m8_t, 512, v64uqi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf4_t,  16,  v1uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16mf2_t,  32,  v2uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m1_t,   64,  v4uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m2_t,  128,  v8uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m4_t,  256, v16uhi)
> +TEST_FIXED_TYPE_INT_ALL (vuint16m8_t,  512, v32uhi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint32mf2_t, 32,  v1usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m1_t,  64,  v2usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m2_t, 128,  v4usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m4_t, 256,  v8usi)
> +TEST_FIXED_TYPE_INT_ALL (vuint32m8_t, 512, v16usi)
> +
> +TEST_FIXED_TYPE_INT_ALL (vuint64m1_t,  64, v1udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m2_t, 128, v2udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m4_t, 256, v4udi)
> +TEST_FIXED_TYPE_INT_ALL (vuint64m8_t, 512, v8udi)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf4_t,  16,  v1hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16mf2_t,  32,  v2hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m1_t,   64,  v4hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m2_t,  128,  v8hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m4_t,  256, v16hf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat16m8_t,  512, v32hf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32mf2_t, 32,  v1sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m1_t,  64,  v2sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m2_t, 128,  v4sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m4_t, 256,  v8sf)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat32m8_t, 512, v16sf)
> +
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m1_t,  64, v1df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m2_t, 128, v2df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m4_t, 256, v4df)
> +TEST_FIXED_TYPE_FLOAT_ALL (vfloat64m8_t, 512, v8df)
> +
> +/* { dg-final { scan-assembler-not {csrr\s+[atx][0-9]+,\s*vlenb} } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> new file mode 100644
> index 00000000000..fd2d352d3e1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits.h
> @@ -0,0 +1,108 @@
> +#ifndef HAVE_DEF_RISCV_RVV_VECTOR_BITS_H
> +#define HAVE_DEF_RISCV_RVV_VECTOR_BITS_H
> +
> +#include "riscv_vector.h"
> +#include "../autovec/vls/def.h"
> +
> +#define DEF_FIXED_TYPE(T, N)                                                   \
> +  typedef T fixed_##T __attribute__((riscv_rvv_vector_bits(N)));
> +
> +#define DEF_FIXED_GLOBAL_VAR(T, N)                                             \
> +  fixed_##T global_fixed_##T##_##N##_bits_var;
> +
> +#define DEF_FIXED_STRUCT_TYPE(T, N)                                            \
> +  struct fixed_##T##_##N##_bits_struct                                         \
> +  {                                                                            \
> +    fixed_##T a, b[2];                                                         \
> +  };
> +
> +#define DEF_FIXED_UNION_TYPE(T, N)                                             \
> +  union fixed_##T##_##N##_bits_union                                           \
> +  {                                                                            \
> +    fixed_##T a, b[3];                                                         \
> +  };
> +
> +#define DEF_FIXED_TYPE_SIZE(T, N)                                              \
> +  void test_fixed_##T##_##N##_bits_size ()                                     \
> +  {                                                                            \
> +    _Static_assert (sizeof (fixed_##T) * 8 == (N < 8 ? 8 : N),                 \
> +                   "Fixed RVV register types should be equal.");              \
> +  }
> +
> +#define DEF_FIXED_TYPE_CVT(T, N, NEW_TYPE)                                     \
> +  NEW_TYPE test_fixed_##T##_##N##_bits_cvt (fixed_##T a)                       \
> +  {                                                                            \
> +    return (NEW_TYPE) a;                                                       \
> +  }
> +
> +#define DEF_FIXED_BINARY(T, N, OP, NAME)                                       \
> +  fixed_##T test_fixed_##T##_##N##_bits_binary_##NAME (fixed_##T a,            \
> +                                                      fixed_##T b)            \
> +  {                                                                            \
> +    return a OP b;                                                             \
> +  }
> +
> +#define DEF_FIXED_UNARY(T, N, OP, NAME)                                        \
> +  fixed_##T test_fixed_##T##_##N##_bits_unary_##NAME (fixed_##T a)             \
> +  {                                                                            \
> +    return OP a;                                                               \
> +  }
> +
> +#define DEF_FIXED_TYPE_CMP(T, N)                                               \
> +  DEF_FIXED_BINARY(T, N, ==, eq)                                               \
> +  DEF_FIXED_BINARY(T, N, !=, ne)                                               \
> +  DEF_FIXED_BINARY(T, N, >,  gt)                                               \
> +  DEF_FIXED_BINARY(T, N, <,  lt)                                               \
> +  DEF_FIXED_BINARY(T, N, >=, ge)                                               \
> +  DEF_FIXED_BINARY(T, N, <=, le)
> +
> +#define DEF_FIXED_TYPE_INT_ALU(T, N)                                           \
> +  DEF_FIXED_BINARY(T, N, +,  add)                                              \
> +  DEF_FIXED_BINARY(T, N, -,  sub)                                              \
> +  DEF_FIXED_BINARY(T, N, *,  mul)                                              \
> +  DEF_FIXED_BINARY(T, N, /,  div)                                              \
> +  DEF_FIXED_BINARY(T, N, %,  mod)                                              \
> +  DEF_FIXED_BINARY(T, N, &,  and)                                              \
> +  DEF_FIXED_BINARY(T, N, |,  ior)                                              \
> +  DEF_FIXED_BINARY(T, N, ^,  xor)                                              \
> +  DEF_FIXED_BINARY(T, N, >>, rsh)                                              \
> +  DEF_FIXED_BINARY(T, N, <<, lsh)                                              \
> +  DEF_FIXED_UNARY(T, N, ~, not)                                                \
> +  DEF_FIXED_UNARY(T, N, -, neg)
> +
> +#define DEF_FIXED_TYPE_FLOAT_ALU(T, N)                                         \
> +  DEF_FIXED_BINARY(T, N, +,  add)                                              \
> +  DEF_FIXED_BINARY(T, N, -,  sub)                                              \
> +  DEF_FIXED_BINARY(T, N, *,  mul)                                              \
> +  DEF_FIXED_BINARY(T, N, /,  div)                                              \
> +  DEF_FIXED_UNARY(T, N, -,  neg)
> +
> +#define TEST_FIXED_TYPE_INT_ALL(T, N, NEW_TYPE)                                \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                          \
> +  DEF_FIXED_TYPE_CMP (T, N)                                                    \
> +  DEF_FIXED_TYPE_INT_ALU (T, N)                                                \
> +
> +#define TEST_FIXED_TYPE_FLOAT_ALL(T, N, NEW_TYPE)                              \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)                                          \
> +  DEF_FIXED_TYPE_CMP (T, N)                                                    \
> +  DEF_FIXED_TYPE_FLOAT_ALU (T, N)                                              \
> +
> +#define TEST_FIXED_TYPE_BOOL_ALL(T, N, NEW_TYPE)                               \
> +  DEF_FIXED_TYPE (T, N)                                                        \
> +  DEF_FIXED_TYPE_SIZE (T, N)                                                   \
> +  DEF_FIXED_GLOBAL_VAR (T, N)                                                  \
> +  DEF_FIXED_STRUCT_TYPE (T, N)                                                 \
> +  DEF_FIXED_UNION_TYPE (T, N)                                                  \
> +  DEF_FIXED_TYPE_CVT (T, N, NEW_TYPE)
> +
> +#endif
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-03-22 10:39 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-06  6:38 [PATCH v1] RISC-V: Introduce gcc attribute riscv_rvv_vector_bits for RVV pan2.li
2024-03-06  6:46 ` juzhe.zhong
2024-03-06  7:27 ` [PATCH v2] " pan2.li
2024-03-06 19:19   ` Vineet Gupta
2024-03-12  2:05     ` Li, Pan2
2024-03-12  6:15 ` [PATCH v3] " pan2.li
2024-03-12 13:25   ` Stefan O'Rear
2024-03-15  1:45     ` Li, Pan2
2024-03-21 13:28       ` Kito Cheng
2024-03-21 13:25   ` Kito Cheng
2024-03-21 14:11     ` Li, Pan2
2024-03-21 14:15       ` Kito Cheng
2024-03-22  6:54 ` [PATCH v4] " pan2.li
2024-03-22 10:05   ` Kito Cheng
2024-03-22 10:39     ` Li, Pan2

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).