riscv_rvv_vector_bits(N) currently requires -mrvv-vector-bits=zvl and
N == VLEN * LMUL, so an object is correctly sized only when the hardware
VLEN matches the zvl it was compiled for; on a larger VLEN, whole-register
accesses can overrun it.

Allow a data typedef to use any power-of-two N that is a multiple of the
element size and no greater than TARGET_MIN_VLEN scaled by the type's LMUL,
with or without -mrvv-vector-bits=zvl.  The type's own mode is poly-sized
under -mrvv-vector-bits=scalable, so give these types a VLS mode of exactly
N bits instead.

gcc/
        * config/riscv/riscv.cc (riscv_build_vls_type): New.
        (riscv_handle_rvv_vector_bits_attribute): Reject a type with no
        mode before taking a size from it.  Reject an argument that is not
        a non-negative integer constant.  Accept a data typedef shorter
        than the vector register.  Print the sizes in the size-mismatch
        diagnostic with %wu instead of a truncating cast to int.
        * doc/extend.texi (RISC-V Attributes): Document
        riscv_rvv_vector_bits.

gcc/testsuite/
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c: Cover a
        mask type, which keeps the strict rule.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-4.c: Likewise.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-5.c: Likewise.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-6.c: Update the
        expected diagnostic.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-19.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-20.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-21.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-25.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-26.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-29.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-30.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-34.c: New test.
        * gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-35.c: New test.
---
 gcc/config/riscv/riscv.cc                     | 100 ++++++++++++++++--
 gcc/doc/extend.texi                           |  36 +++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-19.c |  36 +++++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-20.c |  11 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-21.c |  18 ++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-25.c |   9 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-26.c |   9 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-29.c |  21 ++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-3.c  |   2 +-
 .../riscv/rvv/base/riscv_rvv_vector_bits-30.c |  16 +++
 .../riscv/rvv/base/riscv_rvv_vector_bits-34.c |  26 +++++
 .../riscv/rvv/base/riscv_rvv_vector_bits-35.c |   7 ++
 .../riscv/rvv/base/riscv_rvv_vector_bits-4.c  |   2 +-
 .../riscv/rvv/base/riscv_rvv_vector_bits-5.c  |   2 +-
 .../riscv/rvv/base/riscv_rvv_vector_bits-6.c  |   2 +-
 15 files changed, 282 insertions(+), 15 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-19.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-20.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-21.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-25.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-26.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-29.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-30.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-34.c
 create mode 100644 
gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-35.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 87c24e5dcc1..2a8900171b4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -8247,6 +8247,56 @@ riscv_handle_type_attribute (tree *node 
ATTRIBUTE_UNUSED, tree name, tree args,
   return NULL_TREE;
 }
 
+/* Build a VLS vector type of ARGS_IN_BITS from RVV TYPE and store in *NODE.  
*/
+
+static tree
+riscv_build_vls_type (tree *node, tree type,
+                                  unsigned HOST_WIDE_INT args_in_bits)
+{
+  /* Maximum allowed size under the minimum guaranteed VLEN.  */
+  unsigned HOST_WIDE_INT max_bits
+    = constant_lower_bound (GET_MODE_PRECISION (TYPE_MODE (type)));
+  unsigned HOST_WIDE_INT elt_bits
+    = GET_MODE_PRECISION (GET_MODE_INNER (TYPE_MODE (type)));
+
+  if (args_in_bits > max_bits)
+    {
+      error ("invalid RVV vector size %wu, the maximum size for %qT is %wu",
+            args_in_bits, type, max_bits);
+      return NULL_TREE;
+    }
+
+  if (args_in_bits % elt_bits != 0)
+    {
+      error ("invalid RVV vector size %wu, "
+            "expected a multiple of the %wu-bit element size",
+            args_in_bits, elt_bits);
+      return NULL_TREE;
+    }
+
+  /* Also rejects zero.  */
+  if (!pow2p_hwi (args_in_bits))
+    {
+      error ("invalid RVV vector size %wu, expected a power of 2",
+            args_in_bits);
+      return NULL_TREE;
+    }
+
+  tree new_type = build_vector_type (TREE_TYPE (type), args_in_bits / 
elt_bits);
+
+  /* A size accepted above should have a VLS mode; diagnose it if not.  */
+  if (!VECTOR_MODE_P (TYPE_MODE (new_type)))
+    {
+      error ("invalid RVV vector size %wu, no vector mode of that size is "
+            "available", args_in_bits);
+      return NULL_TREE;
+    }
+
+  *node = new_type;
+
+  return NULL_TREE;
+}
+
 static tree
 riscv_handle_rvv_vls_cc_attribute (tree *, tree name, tree args,
                                   ATTRIBUTE_UNUSED int flags,
@@ -8276,14 +8326,6 @@ riscv_handle_rvv_vector_bits_attribute (tree *node, tree 
name, tree args,
 
   *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))
@@ -8292,6 +8334,17 @@ riscv_handle_rvv_vector_bits_attribute (tree *node, tree 
name, tree args,
       return NULL_TREE;
     }
 
+  if (!VECTOR_MODE_P (TYPE_MODE (type)))
+    {
+      /* riscv_validate_vector_type does not diagnose every element type.  */
+      int count = errorcount;
+      riscv_validate_vector_type (type, "RVV type");
+      if (errorcount == count)
+       error ("%qs applied to unsupported RVV type %qT",
+              "riscv_rvv_vector_bits", type);
+      return NULL_TREE;
+    }
+
   tree size = TREE_VALUE (args);
 
   if (TREE_CODE (size) != INTEGER_CST)
@@ -8300,15 +8353,40 @@ riscv_handle_rvv_vector_bits_attribute (tree *node, 
tree name, tree args,
       return NULL_TREE;
     }
 
+  if (!tree_fits_uhwi_p (size))
+    {
+      error ("%qs requires a non-negative integer constant",
+            "riscv_rvv_vector_bits");
+      return NULL_TREE;
+    }
+
   unsigned HOST_WIDE_INT args_in_bits = tree_to_uhwi (size);
+
+  /* Mask types keep the strict rule; their argument counts lanes, not bits.  
*/
+  bool relax_p = !VECTOR_BOOLEAN_TYPE_P (type);
+
+  if (rvv_vector_bits != RVV_VECTOR_BITS_ZVL)
+    {
+      if (!relax_p)
+       {
+         error ("%qs is only supported when %<-mrvv-vector-bits=zvl%> is "
+                "specified", "riscv_rvv_vector_bits");
+         return NULL_TREE;
+       }
+      return riscv_build_vls_type (node, type, args_in_bits);
+    }
+
   unsigned HOST_WIDE_INT type_mode_bits
     = GET_MODE_PRECISION (TYPE_MODE (type)).to_constant ();
 
+  if (relax_p && args_in_bits != type_mode_bits)
+    return riscv_build_vls_type (node, type, args_in_bits);
+
   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");
+      error ("invalid RVV vector size %<%wu%>, "
+            "expected size is %<%wu%> based on LMUL of type and %qs",
+            args_in_bits, type_mode_bits, "-mrvv-vector-bits=zvl");
       return NULL_TREE;
     }
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 88213d25a89..8a5ed0202aa 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8391,6 +8391,42 @@ Permissible values for this parameter are 
@code{supervisor},
 @code{machine}, and @code{rnmi}.  If there is no parameter, then it
 defaults to @code{machine}.
 
+@atindex @code{riscv_rvv_vector_bits}, RISC-V
+@item riscv_rvv_vector_bits (@var{n})
+This attribute applies to types.
+
+Use this attribute on a @code{typedef} of an RVV type to give it a fixed
+size, so that it can be used where a sizeless type cannot be, such as in a
+structure, a union, or an array.
+
+For a data type, @var{n} may be any power of two that is a multiple of the
+element size and at most the size of the RVV type at the VLEN implied by
+the @code{Zvl*b} extension in the @option{-march} string, which is that
+VLEN scaled by the LMUL of the type.  The object is exactly @var{n} bits
+on any machine with at least that VLEN.
+
+@smallexample
+// With -march=rv64gcv_zvl128b
+typedef vint32m1_t fixed_i32x4 __attribute__((riscv_rvv_vector_bits(128)));
+typedef vint32m1_t fixed_i32x2 __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint32m2_t fixed_i32x8 __attribute__((riscv_rvv_vector_bits(256)));
+@end smallexample
+
+A mask type is accepted only with @option{-mrvv-vector-bits=zvl}, which
+fixes VLEN, and @var{n} must equal its number of lanes at that VLEN.  Such
+an object has the right size only on a machine whose VLEN is exactly the
+value it was compiled for.
+
+@smallexample
+// With -march=rv64gcv_zvl128b -mrvv-vector-bits=zvl
+typedef vbool32_t fixed_b32 __attribute__((riscv_rvv_vector_bits(4)));
+@end smallexample
+
+The type keeps the LMUL it was written against whatever @var{n} is, so a
+short one does not use fewer registers.  A data type that does not fill
+the register is experimental: its ABI is not specified by the RISC-V psABI
+and may change.
+
 @atindex @code{riscv_vector_cc}, RISC-V
 @item riscv_vector_cc
 This attribute applies to functions.
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-19.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-19.c
new file mode 100644
index 00000000000..49a36a108ab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-19.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -mrvv-max-lmul=m8 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_i32x4 __attribute__((riscv_rvv_vector_bits(128)));
+typedef vint32m1_t fixed_i32x2 __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint32m1_t fixed_i32x1 __attribute__((riscv_rvv_vector_bits(32)));
+typedef vint32m2_t fixed_i32x8 __attribute__((riscv_rvv_vector_bits(256)));
+typedef vint32mf2_t fixed_mf2_i32x2 __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint8m1_t fixed_i8x8 __attribute__((riscv_rvv_vector_bits(64)));
+typedef vfloat32m1_t fixed_f32x2 __attribute__((riscv_rvv_vector_bits(64)));
+
+_Static_assert (sizeof (fixed_i32x4) == 16, "fixed_i32x4");
+_Static_assert (sizeof (fixed_i32x2) == 8, "fixed_i32x2");
+_Static_assert (sizeof (fixed_i32x1) == 4, "fixed_i32x1");
+_Static_assert (sizeof (fixed_i32x8) == 32, "fixed_i32x8");
+_Static_assert (sizeof (fixed_mf2_i32x2) == 8, "fixed_mf2_i32x2");
+_Static_assert (sizeof (fixed_i8x8) == 8, "fixed_i8x8");
+_Static_assert (sizeof (fixed_f32x2) == 8, "fixed_f32x2");
+
+fixed_i32x4 global_var;
+
+struct s
+{
+  fixed_i32x2 a;
+  int b;
+};
+
+union u
+{
+  fixed_i32x2 a;
+  fixed_i8x8 b;
+};
+
+fixed_i32x4 array[4];
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-20.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-20.c
new file mode 100644
index 00000000000..390171dad9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-20.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t too_large __attribute__((riscv_rvv_vector_bits(256))); /* { 
dg-error "invalid RVV vector size 256, the maximum size for '\[^']*' is 128" } 
*/
+typedef vint32mf2_t too_large_mf2 __attribute__((riscv_rvv_vector_bits(128))); 
/* { dg-error "invalid RVV vector size 128, the maximum size for '\[^']*' is 
64" } */
+typedef vint32m1_t not_pow2 __attribute__((riscv_rvv_vector_bits(96))); /* { 
dg-error "invalid RVV vector size 96, expected a power of 2" } */
+typedef vint32m1_t not_multiple __attribute__((riscv_rvv_vector_bits(16))); /* 
{ dg-error "invalid RVV vector size 16, expected a multiple of the 32-bit 
element size" } */
+typedef vint32m1_t zero __attribute__((riscv_rvv_vector_bits(0))); /* { 
dg-error "invalid RVV vector size 0, expected a power of 2" } */
+typedef vbool32_t mask __attribute__((riscv_rvv_vector_bits(4))); /* { 
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-21.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-21.c
new file mode 100644
index 00000000000..13e7d5e6488
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-21.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t fixed_i32x4 __attribute__((riscv_rvv_vector_bits(128)));
+
+void
+store (fixed_i32x4 *p, fixed_i32x4 *q)
+{
+  *p = *q + *q;
+}
+
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,4,e32,m1} 1 } } */
+/* { dg-final { scan-assembler {vle32\.v} } } */
+/* { dg-final { scan-assembler {vse32\.v} } } */
+/* { dg-final { scan-assembler-not {vl1re32\.v} } } */
+/* { dg-final { scan-assembler-not {vs1r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-25.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-25.c
new file mode 100644
index 00000000000..c3ed492ea78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-25.c
@@ -0,0 +1,9 @@
+/* An RVV type with no mode has no size for the attribute to check against.  */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -mrvv-vector-bits=zvl -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vfloat16m1_t f16 __attribute__((riscv_rvv_vector_bits(64))); /* { 
dg-error "requires the zvfhmin or zvfh ISA extension" } */
+typedef vfloat16m1_t f16_zero __attribute__((riscv_rvv_vector_bits(0))); /* { 
dg-error "requires the zvfhmin or zvfh ISA extension" } */
+typedef vbfloat16m1_t bf16 __attribute__((riscv_rvv_vector_bits(64))); /* { 
dg-error "applied to unsupported RVV type" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-26.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-26.c
new file mode 100644
index 00000000000..58969728684
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-26.c
@@ -0,0 +1,9 @@
+/* Same as riscv_rvv_vector_bits-25.c, without -mrvv-vector-bits=zvl.  */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vfloat16m1_t f16 __attribute__((riscv_rvv_vector_bits(64))); /* { 
dg-error "requires the zvfhmin or zvfh ISA extension" } */
+typedef vfloat16m1_t f16_zero __attribute__((riscv_rvv_vector_bits(0))); /* { 
dg-error "requires the zvfhmin or zvfh ISA extension" } */
+typedef vbfloat16m1_t bf16 __attribute__((riscv_rvv_vector_bits(64))); /* { 
dg-error "applied to unsupported RVV type" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-29.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-29.c
new file mode 100644
index 00000000000..386e6db1c37
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-29.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -mrvv-max-lmul=m2 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t m1_eq __attribute__((riscv_rvv_vector_bits(128)));
+typedef vint32m1_t m1_lt __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint32m1_t m1_min __attribute__((riscv_rvv_vector_bits(32)));
+typedef vint32m1_t m1_too __attribute__((riscv_rvv_vector_bits(256))); /* { 
dg-error "invalid RVV vector size 256, the maximum size for '\[^']*' is 128" } 
*/
+
+typedef vint32m2_t m2_eq __attribute__((riscv_rvv_vector_bits(256)));
+typedef vint32m2_t m2_lt __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint32m2_t m2_too __attribute__((riscv_rvv_vector_bits(512))); /* { 
dg-error "invalid RVV vector size 512, the maximum size for '\[^']*' is 256" } 
*/
+
+typedef vint32mf2_t mf2_eq __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint32mf2_t mf2_lt __attribute__((riscv_rvv_vector_bits(32)));
+typedef vint32mf2_t mf2_too __attribute__((riscv_rvv_vector_bits(128))); /* { 
dg-error "invalid RVV vector size 128, the maximum size for '\[^']*' is 64" } */
+
+typedef vint32m1_t m1_npow2 __attribute__((riscv_rvv_vector_bits(96))); /* { 
dg-error "invalid RVV vector size 96, expected a power of 2" } */
+
+typedef vbool32_t mask_short __attribute__((riscv_rvv_vector_bits(4))); /* { 
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-3.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-3.c
index e1b0664eacb..6429ac5cfd6 100644
--- 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
@@ -3,4 +3,4 @@
 
 #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" } */
+typedef vbool32_t fixed_vbool32_t __attribute__((riscv_rvv_vector_bits(4))); 
/* { 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-30.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-30.c
new file mode 100644
index 00000000000..6714b48e741
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-30.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -mrvv-max-lmul=m2 -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t m1_eq __attribute__((riscv_rvv_vector_bits(256)));
+typedef vint32m1_t m1_lt __attribute__((riscv_rvv_vector_bits(128)));
+typedef vint32m1_t m1_too __attribute__((riscv_rvv_vector_bits(512))); /* { 
dg-error "invalid RVV vector size 512, the maximum size for '\[^']*' is 256" } 
*/
+
+typedef vint32m2_t m2_eq __attribute__((riscv_rvv_vector_bits(512)));
+typedef vint32m2_t m2_lt __attribute__((riscv_rvv_vector_bits(256)));
+typedef vint32m2_t m2_too __attribute__((riscv_rvv_vector_bits(1024))); /* { 
dg-error "invalid RVV vector size 1024, the maximum size for '\[^']*' is 512" } 
*/
+
+typedef vint32mf2_t mf2_eq __attribute__((riscv_rvv_vector_bits(128)));
+typedef vint32mf2_t mf2_lt __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint32mf2_t mf2_too __attribute__((riscv_rvv_vector_bits(256))); /* { 
dg-error "invalid RVV vector size 256, the maximum size for '\[^']*' is 128" } 
*/
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-34.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-34.c
new file mode 100644
index 00000000000..df2ef303c4e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-34.c
@@ -0,0 +1,26 @@
+/* A shorter object must use VL-limited accesses, not whole-register ones.  */
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl128b -mabi=lp64d -mrvv-vector-bits=zvl -O3" 
} */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t shorter __attribute__((riscv_rvv_vector_bits(64)));
+typedef vint32m1_t full __attribute__((riscv_rvv_vector_bits(128)));
+
+void
+store_shorter (shorter *p, shorter *q)
+{
+  *p = *q + *q;
+}
+
+void
+store_full (full *p, full *q)
+{
+  *p = *q + *q;
+}
+
+/* { dg-final { scan-assembler-times {vsetivli\s+zero,2,e32,mf2} 1 } } */
+/* { dg-final { scan-assembler-times {vle32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vse32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vl1re32\.v} 1 } } */
+/* { dg-final { scan-assembler-times {vs1r\.v} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-35.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-35.c
new file mode 100644
index 00000000000..4a0d3241b3c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/riscv_rvv_vector_bits-35.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3" } */
+
+#include "riscv_vector.h"
+
+typedef vint32m1_t negative __attribute__((riscv_rvv_vector_bits(-1))); /* { 
dg-error "'riscv_rvv_vector_bits' requires a non-negative integer constant" } */
+typedef vint32m1_t not_constant __attribute__((riscv_rvv_vector_bits(1.0))); 
/* { dg-error "'riscv_rvv_vector_bits' requires an integer constant" } */
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
index eef15654110..8d1045e566c 100644
--- 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
@@ -3,4 +3,4 @@
 
 #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'" } */
+typedef vbool32_t fixed_vbool32_t __attribute__((riscv_rvv_vector_bits(4))); 
/* { dg-error "invalid RVV vector size '4', expected size is '8' 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
index 6b4f19cd9f2..4cd2fb3be2e 100644
--- 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
@@ -3,4 +3,4 @@
 
 #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'" } */
+typedef vbool16_t fixed_vbool16_t __attribute__((riscv_rvv_vector_bits(4))); 
/* { dg-error "invalid RVV vector size '4', expected size is '8' 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
index bc346917fe5..13f2ceaba1d 100644
--- 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
@@ -3,4 +3,4 @@
 
 #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'" } */
+typedef vint32mf2_t fixed_vint32mf2_t 
__attribute__((riscv_rvv_vector_bits(256))); /* { dg-error "invalid RVV vector 
size 256, the maximum size for 'vint32mf2_t' is 128" } */
-- 
2.54.0

Reply via email to