public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment
@ 2023-03-03  2:31 pan2.li
  2023-03-03  8:06 ` Kito Cheng
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: pan2.li @ 2023-03-03  2:31 UTC (permalink / raw)
  To: gcc-patches
  Cc: juzhe.zhong, kito.cheng, rguenther, pan2.li, richard.sandiford

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

	Fix the bug of the rvv bool mode precision with the adjustment.
	The bits size of vbool*_t will be adjusted to
	[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
	adjusted mode precison of vbool*_t will help underlying pass to
	make the right decision for both the correctness and optimization.

	Given below sample code:
	void test_1(int8_t * restrict in, int8_t * restrict out)
	{
	  vbool8_t v2 = *(vbool8_t*)in;
	  vbool16_t v5 = *(vbool16_t*)in;
	  *(vbool16_t*)(out + 200) = v5;
	  *(vbool8_t*)(out + 100) = v2;
	}

	Before the precision adjustment:
	addi    a4,a1,100
	vsetvli a5,zero,e8,m1,ta,ma
	addi    a1,a1,200
	vlm.v   v24,0(a0)
	vsm.v   v24,0(a4)
	// Need one vsetvli and vlm.v for correctness here.
	vsm.v   v24,0(a1)

	After the precision adjustment:
	csrr    t0,vlenb
	slli    t1,t0,1
	csrr    a3,vlenb
	sub     sp,sp,t1
	slli    a4,a3,1
	add     a4,a4,sp
	sub     a3,a4,a3
	vsetvli a5,zero,e8,m1,ta,ma
	addi    a2,a1,200
	vlm.v   v24,0(a0)
	vsm.v   v24,0(a3)
	addi    a1,a1,100
	vsetvli a4,zero,e8,mf2,ta,ma
	csrr    t0,vlenb
	vlm.v   v25,0(a3)
	vsm.v   v25,0(a2)
	slli    t1,t0,1
	vsetvli a5,zero,e8,m1,ta,ma
	vsm.v   v24,0(a1)
	add     sp,sp,t1
	jr      ra

	However, there may be some optimization opportunates after
	the mode precision adjustment. It can be token care of in
	the RISC-V backend in the underlying separted PR(s).

	PR 108185
	PR 108654

gcc/ChangeLog:

	* config/riscv/riscv-modes.def (ADJUST_PRECISION):
	* config/riscv/riscv.cc (riscv_v_adjust_precision):
	* config/riscv/riscv.h (riscv_v_adjust_precision):
	* genmodes.cc (ADJUST_PRECISION):
	(emit_mode_adjustments):

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/pr108185-1.c: New test.
	* gcc.target/riscv/pr108185-2.c: New test.
	* gcc.target/riscv/pr108185-3.c: New test.
	* gcc.target/riscv/pr108185-4.c: New test.
	* gcc.target/riscv/pr108185-5.c: New test.
	* gcc.target/riscv/pr108185-6.c: New test.
	* gcc.target/riscv/pr108185-7.c: New test.
	* gcc.target/riscv/pr108185-8.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
---
 gcc/config/riscv/riscv-modes.def            |  8 +++
 gcc/config/riscv/riscv.cc                   | 12 ++++
 gcc/config/riscv/riscv.h                    |  1 +
 gcc/genmodes.cc                             | 26 ++++++-
 gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
 12 files changed, 598 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c

diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
index d5305efa8a6..110bddce851 100644
--- a/gcc/config/riscv/riscv-modes.def
+++ b/gcc/config/riscv/riscv-modes.def
@@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
 ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
 ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
 
+ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1));
+ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2));
+ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4));
+ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8));
+ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16));
+ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32));
+ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64));
+
 /*
    | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
    |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f11b7949a49..ac5c2527fde 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
   return scale;
 }
 
+/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
+   PRECISION size for corresponding machine_mode.  */
+
+poly_int64
+riscv_v_adjust_precision (machine_mode mode, int scale)
+{
+  if (riscv_v_ext_vector_mode_p (mode))
+    return riscv_vector_chunks * scale;
+
+  return scale;
+}
+
 /* Return true if X is a valid address for machine mode MODE.  If it is,
    fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
    effect.  */
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 5bc7f2f467d..15b9317a8ce 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;
 extern unsigned riscv_bytes_per_vector_chunk;
 extern poly_uint16 riscv_vector_chunks;
 extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
+extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
 /* The number of bits and bytes in a RVV vector.  */
 #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
 #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index 2d418f09aab..4b262040ff8 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;
 static struct mode_adjust *adj_format;
 static struct mode_adjust *adj_ibit;
 static struct mode_adjust *adj_fbit;
+static struct mode_adjust *adj_precision;
 
 /* Mode class operations.  */
 static enum mode_class
@@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
 #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
 #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
 #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
+#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM)
 #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
 #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
 #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
@@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void)
 static void
 emit_mode_adjustments (void)
 {
+  int c;
   struct mode_adjust *a;
   struct mode_data *m;
 
@@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
 	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
 	      m->name, m->name);
       printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
-      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
-	      " BITS_PER_UNIT);\n", m->name, m->name);
+      printf ("    if (!multiple_p (mode_precision[E_%smode],"
+	      " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
+      printf ("      mode_size[E_%smode] = -1;\n", m->name);
       printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
       printf ("    adjust_mode_mask (E_%smode);\n", m->name);
       printf ("  }\n");
@@ -1963,6 +1967,24 @@ emit_mode_adjustments (void)
     printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
 	    a->file, a->line, a->mode->name, a->adjustment);
 
+  /* Adjust precision to the actual bits size.  */
+  for (a = adj_precision; a; a = a->next)
+    switch (a->mode->cl)
+      {
+	case MODE_VECTOR_BOOL:
+	  printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
+		  a->adjustment);
+	  printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
+	  break;
+	default:
+	  break;
+      }
+
+  /* Ensure there is no mode size equals -1.  */
+  for_all_modes (c, m)
+    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
+	    m->name, m->name);
+
   puts ("}");
 }
 
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
new file mode 100644
index 00000000000..e70960c5b6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
new file mode 100644
index 00000000000..dcc7a644a88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
new file mode 100644
index 00000000000..3af0513e006
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
new file mode 100644
index 00000000000..ea3c360d756
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
new file mode 100644
index 00000000000..9fc659d2402
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
new file mode 100644
index 00000000000..98275e5267d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
new file mode 100644
index 00000000000..8f6f0b11f09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
new file mode 100644
index 00000000000..d96959dd064
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
@@ -0,0 +1,77 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
-- 
2.34.1


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

* Re: [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-03  2:31 [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment pan2.li
@ 2023-03-03  8:06 ` Kito Cheng
  2023-03-06 10:12   ` Li, Pan2
  2023-03-06 13:41 ` Richard Sandiford
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Kito Cheng @ 2023-03-03  8:06 UTC (permalink / raw)
  To: pan2.li; +Cc: gcc-patches, juzhe.zhong, rguenther, richard.sandiford

Thanks!

RISC-V part is LGTM, and I would like to wait for Richard Sandiford to
say OK to the genmodes.cc part :)


On Fri, Mar 3, 2023 at 10:31 AM <pan2.li@intel.com> wrote:
>
> From: Pan Li <pan2.li@intel.com>
>
>         Fix the bug of the rvv bool mode precision with the adjustment.
>         The bits size of vbool*_t will be adjusted to
>         [1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
>         adjusted mode precison of vbool*_t will help underlying pass to
>         make the right decision for both the correctness and optimization.
>
>         Given below sample code:
>         void test_1(int8_t * restrict in, int8_t * restrict out)
>         {
>           vbool8_t v2 = *(vbool8_t*)in;
>           vbool16_t v5 = *(vbool16_t*)in;
>           *(vbool16_t*)(out + 200) = v5;
>           *(vbool8_t*)(out + 100) = v2;
>         }
>
>         Before the precision adjustment:
>         addi    a4,a1,100
>         vsetvli a5,zero,e8,m1,ta,ma
>         addi    a1,a1,200
>         vlm.v   v24,0(a0)
>         vsm.v   v24,0(a4)
>         // Need one vsetvli and vlm.v for correctness here.
>         vsm.v   v24,0(a1)
>
>         After the precision adjustment:
>         csrr    t0,vlenb
>         slli    t1,t0,1
>         csrr    a3,vlenb
>         sub     sp,sp,t1
>         slli    a4,a3,1
>         add     a4,a4,sp
>         sub     a3,a4,a3
>         vsetvli a5,zero,e8,m1,ta,ma
>         addi    a2,a1,200
>         vlm.v   v24,0(a0)
>         vsm.v   v24,0(a3)
>         addi    a1,a1,100
>         vsetvli a4,zero,e8,mf2,ta,ma
>         csrr    t0,vlenb
>         vlm.v   v25,0(a3)
>         vsm.v   v25,0(a2)
>         slli    t1,t0,1
>         vsetvli a5,zero,e8,m1,ta,ma
>         vsm.v   v24,0(a1)
>         add     sp,sp,t1
>         jr      ra
>
>         However, there may be some optimization opportunates after
>         the mode precision adjustment. It can be token care of in
>         the RISC-V backend in the underlying separted PR(s).
>
>         PR 108185
>         PR 108654
>
> gcc/ChangeLog:
>
>         * config/riscv/riscv-modes.def (ADJUST_PRECISION):
>         * config/riscv/riscv.cc (riscv_v_adjust_precision):
>         * config/riscv/riscv.h (riscv_v_adjust_precision):
>         * genmodes.cc (ADJUST_PRECISION):
>         (emit_mode_adjustments):
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/pr108185-1.c: New test.
>         * gcc.target/riscv/pr108185-2.c: New test.
>         * gcc.target/riscv/pr108185-3.c: New test.
>         * gcc.target/riscv/pr108185-4.c: New test.
>         * gcc.target/riscv/pr108185-5.c: New test.
>         * gcc.target/riscv/pr108185-6.c: New test.
>         * gcc.target/riscv/pr108185-7.c: New test.
>         * gcc.target/riscv/pr108185-8.c: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-modes.def            |  8 +++
>  gcc/config/riscv/riscv.cc                   | 12 ++++
>  gcc/config/riscv/riscv.h                    |  1 +
>  gcc/genmodes.cc                             | 26 ++++++-
>  gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
>  12 files changed, 598 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c
>
> diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
> index d5305efa8a6..110bddce851 100644
> --- a/gcc/config/riscv/riscv-modes.def
> +++ b/gcc/config/riscv/riscv-modes.def
> @@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
>
> +ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1));
> +ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2));
> +ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4));
> +ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8));
> +ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16));
> +ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32));
> +ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64));
> +
>  /*
>     | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
>     |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index f11b7949a49..ac5c2527fde 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
>    return scale;
>  }
>
> +/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
> +   PRECISION size for corresponding machine_mode.  */
> +
> +poly_int64
> +riscv_v_adjust_precision (machine_mode mode, int scale)
> +{
> +  if (riscv_v_ext_vector_mode_p (mode))
> +    return riscv_vector_chunks * scale;
> +
> +  return scale;
> +}
> +
>  /* Return true if X is a valid address for machine mode MODE.  If it is,
>     fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
>     effect.  */
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
> index 5bc7f2f467d..15b9317a8ce 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;
>  extern unsigned riscv_bytes_per_vector_chunk;
>  extern poly_uint16 riscv_vector_chunks;
>  extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
> +extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
>  /* The number of bits and bytes in a RVV vector.  */
>  #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
>  #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
> index 2d418f09aab..4b262040ff8 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;
>  static struct mode_adjust *adj_format;
>  static struct mode_adjust *adj_ibit;
>  static struct mode_adjust *adj_fbit;
> +static struct mode_adjust *adj_precision;
>
>  /* Mode class operations.  */
>  static enum mode_class
> @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
>  #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
>  #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
>  #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
> +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM)
>  #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
>  #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
>  #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
> @@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void)
>  static void
>  emit_mode_adjustments (void)
>  {
> +  int c;
>    struct mode_adjust *a;
>    struct mode_data *m;
>
> @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
>               " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
>               m->name, m->name);
>        printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
> -      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
> -             " BITS_PER_UNIT);\n", m->name, m->name);
> +      printf ("    if (!multiple_p (mode_precision[E_%smode],"
> +             " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
> +      printf ("      mode_size[E_%smode] = -1;\n", m->name);
>        printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
>        printf ("    adjust_mode_mask (E_%smode);\n", m->name);
>        printf ("  }\n");
> @@ -1963,6 +1967,24 @@ emit_mode_adjustments (void)
>      printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
>             a->file, a->line, a->mode->name, a->adjustment);
>
> +  /* Adjust precision to the actual bits size.  */
> +  for (a = adj_precision; a; a = a->next)
> +    switch (a->mode->cl)
> +      {
> +       case MODE_VECTOR_BOOL:
> +         printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
> +                 a->adjustment);
> +         printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
> +         break;
> +       default:
> +         break;
> +      }
> +
> +  /* Ensure there is no mode size equals -1.  */
> +  for_all_modes (c, m)
> +    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
> +           m->name, m->name);
> +
>    puts ("}");
>  }
>
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> new file mode 100644
> index 00000000000..e70960c5b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> new file mode 100644
> index 00000000000..dcc7a644a88
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> new file mode 100644
> index 00000000000..3af0513e006
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> new file mode 100644
> index 00000000000..ea3c360d756
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> new file mode 100644
> index 00000000000..9fc659d2402
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> new file mode 100644
> index 00000000000..98275e5267d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> new file mode 100644
> index 00000000000..8f6f0b11f09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> new file mode 100644
> index 00000000000..d96959dd064
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> @@ -0,0 +1,77 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> --
> 2.34.1
>

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

* RE: [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-03  8:06 ` Kito Cheng
@ 2023-03-06 10:12   ` Li, Pan2
  0 siblings, 0 replies; 10+ messages in thread
From: Li, Pan2 @ 2023-03-06 10:12 UTC (permalink / raw)
  To: Kito Cheng; +Cc: gcc-patches, juzhe.zhong, rguenther, richard.sandiford

Thank you, Kito.

Hi Richard Sandiford,

Could you please help to review this PATCH continuously? Thank you and have a nice day!

Pan

-----Original Message-----
From: Kito Cheng <kito.cheng@sifive.com> 
Sent: Friday, March 3, 2023 4:06 PM
To: Li, Pan2 <pan2.li@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; rguenther@suse.de; richard.sandiford@arm.com
Subject: Re: [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment

Thanks!

RISC-V part is LGTM, and I would like to wait for Richard Sandiford to say OK to the genmodes.cc part :)


On Fri, Mar 3, 2023 at 10:31 AM <pan2.li@intel.com> wrote:
>
> From: Pan Li <pan2.li@intel.com>
>
>         Fix the bug of the rvv bool mode precision with the adjustment.
>         The bits size of vbool*_t will be adjusted to
>         [1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
>         adjusted mode precison of vbool*_t will help underlying pass to
>         make the right decision for both the correctness and optimization.
>
>         Given below sample code:
>         void test_1(int8_t * restrict in, int8_t * restrict out)
>         {
>           vbool8_t v2 = *(vbool8_t*)in;
>           vbool16_t v5 = *(vbool16_t*)in;
>           *(vbool16_t*)(out + 200) = v5;
>           *(vbool8_t*)(out + 100) = v2;
>         }
>
>         Before the precision adjustment:
>         addi    a4,a1,100
>         vsetvli a5,zero,e8,m1,ta,ma
>         addi    a1,a1,200
>         vlm.v   v24,0(a0)
>         vsm.v   v24,0(a4)
>         // Need one vsetvli and vlm.v for correctness here.
>         vsm.v   v24,0(a1)
>
>         After the precision adjustment:
>         csrr    t0,vlenb
>         slli    t1,t0,1
>         csrr    a3,vlenb
>         sub     sp,sp,t1
>         slli    a4,a3,1
>         add     a4,a4,sp
>         sub     a3,a4,a3
>         vsetvli a5,zero,e8,m1,ta,ma
>         addi    a2,a1,200
>         vlm.v   v24,0(a0)
>         vsm.v   v24,0(a3)
>         addi    a1,a1,100
>         vsetvli a4,zero,e8,mf2,ta,ma
>         csrr    t0,vlenb
>         vlm.v   v25,0(a3)
>         vsm.v   v25,0(a2)
>         slli    t1,t0,1
>         vsetvli a5,zero,e8,m1,ta,ma
>         vsm.v   v24,0(a1)
>         add     sp,sp,t1
>         jr      ra
>
>         However, there may be some optimization opportunates after
>         the mode precision adjustment. It can be token care of in
>         the RISC-V backend in the underlying separted PR(s).
>
>         PR 108185
>         PR 108654
>
> gcc/ChangeLog:
>
>         * config/riscv/riscv-modes.def (ADJUST_PRECISION):
>         * config/riscv/riscv.cc (riscv_v_adjust_precision):
>         * config/riscv/riscv.h (riscv_v_adjust_precision):
>         * genmodes.cc (ADJUST_PRECISION):
>         (emit_mode_adjustments):
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/pr108185-1.c: New test.
>         * gcc.target/riscv/pr108185-2.c: New test.
>         * gcc.target/riscv/pr108185-3.c: New test.
>         * gcc.target/riscv/pr108185-4.c: New test.
>         * gcc.target/riscv/pr108185-5.c: New test.
>         * gcc.target/riscv/pr108185-6.c: New test.
>         * gcc.target/riscv/pr108185-7.c: New test.
>         * gcc.target/riscv/pr108185-8.c: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-modes.def            |  8 +++
>  gcc/config/riscv/riscv.cc                   | 12 ++++
>  gcc/config/riscv/riscv.h                    |  1 +
>  gcc/genmodes.cc                             | 26 ++++++-
>  gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
>  12 files changed, 598 insertions(+), 2 deletions(-)  create mode 
> 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c
>
> diff --git a/gcc/config/riscv/riscv-modes.def 
> b/gcc/config/riscv/riscv-modes.def
> index d5305efa8a6..110bddce851 100644
> --- a/gcc/config/riscv/riscv-modes.def
> +++ b/gcc/config/riscv/riscv-modes.def
> @@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * 
> riscv_bytes_per_vector_chunk);  ADJUST_BYTESIZE (VNx32BI, 
> riscv_vector_chunks * riscv_bytes_per_vector_chunk);  ADJUST_BYTESIZE 
> (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
>
> +ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1)); 
> +ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2)); 
> +ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4)); 
> +ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8)); 
> +ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 
> +16)); ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision 
> +(VNx32BImode, 32)); ADJUST_PRECISION (VNx64BI, 
> +riscv_v_adjust_precision (VNx64BImode, 64));
> +
>  /*
>     | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
>     |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc 
> index f11b7949a49..ac5c2527fde 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
>    return scale;
>  }
>
> +/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
> +   PRECISION size for corresponding machine_mode.  */
> +
> +poly_int64
> +riscv_v_adjust_precision (machine_mode mode, int scale) {
> +  if (riscv_v_ext_vector_mode_p (mode))
> +    return riscv_vector_chunks * scale;
> +
> +  return scale;
> +}
> +
>  /* Return true if X is a valid address for machine mode MODE.  If it is,
>     fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
>     effect.  */
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 
> 5bc7f2f467d..15b9317a8ce 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;  extern 
> unsigned riscv_bytes_per_vector_chunk;  extern poly_uint16 
> riscv_vector_chunks;  extern poly_int64 riscv_v_adjust_nunits (enum 
> machine_mode, int);
> +extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
>  /* The number of bits and bytes in a RVV vector.  */  #define 
> BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * 
> riscv_bytes_per_vector_chunk * 8))  #define BYTES_PER_RISCV_VECTOR 
> (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk)) 
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc index 
> 2d418f09aab..4b262040ff8 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;  static 
> struct mode_adjust *adj_format;  static struct mode_adjust *adj_ibit;  
> static struct mode_adjust *adj_fbit;
> +static struct mode_adjust *adj_precision;
>
>  /* Mode class operations.  */
>  static enum mode_class
> @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
>  #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
>  #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, 
> RANDOM)  #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, 
> RANDOM, RANDOM)
> +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, 
> +RANDOM)
>  #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
>  #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)  
> #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM) @@ 
> -1794,6 +1796,7 @@ emit_real_format_for_mode (void)  static void  
> emit_mode_adjustments (void)  {
> +  int c;
>    struct mode_adjust *a;
>    struct mode_data *m;
>
> @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
>               " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
>               m->name, m->name);
>        printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
> -      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
> -             " BITS_PER_UNIT);\n", m->name, m->name);
> +      printf ("    if (!multiple_p (mode_precision[E_%smode],"
> +             " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
> +      printf ("      mode_size[E_%smode] = -1;\n", m->name);
>        printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
>        printf ("    adjust_mode_mask (E_%smode);\n", m->name);
>        printf ("  }\n");
> @@ -1963,6 +1967,24 @@ emit_mode_adjustments (void)
>      printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
>             a->file, a->line, a->mode->name, a->adjustment);
>
> +  /* Adjust precision to the actual bits size.  */  for (a = 
> + adj_precision; a; a = a->next)
> +    switch (a->mode->cl)
> +      {
> +       case MODE_VECTOR_BOOL:
> +         printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
> +                 a->adjustment);
> +         printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
> +         break;
> +       default:
> +         break;
> +      }
> +
> +  /* Ensure there is no mode size equals -1.  */  for_all_modes (c, 
> + m)
> +    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
> +           m->name, m->name);
> +
>    puts ("}");
>  }
>
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> new file mode 100644
> index 00000000000..e70960c5b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> new file mode 100644
> index 00000000000..dcc7a644a88
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> new file mode 100644
> index 00000000000..3af0513e006
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> new file mode 100644
> index 00000000000..ea3c360d756
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> new file mode 100644
> index 00000000000..9fc659d2402
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> new file mode 100644
> index 00000000000..98275e5267d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> new file mode 100644
> index 00000000000..8f6f0b11f09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> new file mode 100644
> index 00000000000..d96959dd064
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> @@ -0,0 +1,77 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> --
> 2.34.1
>

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

* Re: [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-03  2:31 [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment pan2.li
  2023-03-03  8:06 ` Kito Cheng
@ 2023-03-06 13:41 ` Richard Sandiford
  2023-03-06 14:59   ` Li, Pan2
  2023-03-06 14:57 ` [PATCH v4] " pan2.li
  2023-03-07 12:05 ` [PATCH v5] " pan2.li
  3 siblings, 1 reply; 10+ messages in thread
From: Richard Sandiford @ 2023-03-06 13:41 UTC (permalink / raw)
  To: pan2.li; +Cc: gcc-patches, juzhe.zhong, kito.cheng, rguenther

pan2.li@intel.com writes:
> From: Pan Li <pan2.li@intel.com>
>
> 	Fix the bug of the rvv bool mode precision with the adjustment.
> 	The bits size of vbool*_t will be adjusted to
> 	[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
> 	adjusted mode precison of vbool*_t will help underlying pass to
> 	make the right decision for both the correctness and optimization.
>
> 	Given below sample code:
> 	void test_1(int8_t * restrict in, int8_t * restrict out)
> 	{
> 	  vbool8_t v2 = *(vbool8_t*)in;
> 	  vbool16_t v5 = *(vbool16_t*)in;
> 	  *(vbool16_t*)(out + 200) = v5;
> 	  *(vbool8_t*)(out + 100) = v2;
> 	}
>
> 	Before the precision adjustment:
> 	addi    a4,a1,100
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a1,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a4)
> 	// Need one vsetvli and vlm.v for correctness here.
> 	vsm.v   v24,0(a1)
>
> 	After the precision adjustment:
> 	csrr    t0,vlenb
> 	slli    t1,t0,1
> 	csrr    a3,vlenb
> 	sub     sp,sp,t1
> 	slli    a4,a3,1
> 	add     a4,a4,sp
> 	sub     a3,a4,a3
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a2,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a3)
> 	addi    a1,a1,100
> 	vsetvli a4,zero,e8,mf2,ta,ma
> 	csrr    t0,vlenb
> 	vlm.v   v25,0(a3)
> 	vsm.v   v25,0(a2)
> 	slli    t1,t0,1
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	vsm.v   v24,0(a1)
> 	add     sp,sp,t1
> 	jr      ra
>
> 	However, there may be some optimization opportunates after
> 	the mode precision adjustment. It can be token care of in
> 	the RISC-V backend in the underlying separted PR(s).
>
> 	PR 108185
> 	PR 108654
>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv-modes.def (ADJUST_PRECISION):
> 	* config/riscv/riscv.cc (riscv_v_adjust_precision):
> 	* config/riscv/riscv.h (riscv_v_adjust_precision):
> 	* genmodes.cc (ADJUST_PRECISION):
> 	(emit_mode_adjustments):
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/pr108185-1.c: New test.
> 	* gcc.target/riscv/pr108185-2.c: New test.
> 	* gcc.target/riscv/pr108185-3.c: New test.
> 	* gcc.target/riscv/pr108185-4.c: New test.
> 	* gcc.target/riscv/pr108185-5.c: New test.
> 	* gcc.target/riscv/pr108185-6.c: New test.
> 	* gcc.target/riscv/pr108185-7.c: New test.
> 	* gcc.target/riscv/pr108185-8.c: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-modes.def            |  8 +++
>  gcc/config/riscv/riscv.cc                   | 12 ++++
>  gcc/config/riscv/riscv.h                    |  1 +
>  gcc/genmodes.cc                             | 26 ++++++-
>  gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
>  12 files changed, 598 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c
>
> diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
> index d5305efa8a6..110bddce851 100644
> --- a/gcc/config/riscv/riscv-modes.def
> +++ b/gcc/config/riscv/riscv-modes.def
> @@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
>  
> +ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1));
> +ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2));
> +ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4));
> +ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8));
> +ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16));
> +ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32));
> +ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64));
> +
>  /*
>     | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
>     |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index f11b7949a49..ac5c2527fde 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
>    return scale;
>  }
>  
> +/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
> +   PRECISION size for corresponding machine_mode.  */
> +
> +poly_int64
> +riscv_v_adjust_precision (machine_mode mode, int scale)
> +{
> +  if (riscv_v_ext_vector_mode_p (mode))
> +    return riscv_vector_chunks * scale;
> +
> +  return scale;
> +}
> +
>  /* Return true if X is a valid address for machine mode MODE.  If it is,
>     fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
>     effect.  */
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
> index 5bc7f2f467d..15b9317a8ce 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;
>  extern unsigned riscv_bytes_per_vector_chunk;
>  extern poly_uint16 riscv_vector_chunks;
>  extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
> +extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
>  /* The number of bits and bytes in a RVV vector.  */
>  #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
>  #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
> index 2d418f09aab..4b262040ff8 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;
>  static struct mode_adjust *adj_format;
>  static struct mode_adjust *adj_ibit;
>  static struct mode_adjust *adj_fbit;
> +static struct mode_adjust *adj_precision;
>  
>  /* Mode class operations.  */
>  static enum mode_class
> @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
>  #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
>  #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
>  #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
> +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM)
>  #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
>  #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
>  #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
> @@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void)
>  static void
>  emit_mode_adjustments (void)
>  {
> +  int c;
>    struct mode_adjust *a;
>    struct mode_data *m;
>  
> @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
>  	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
>  	      m->name, m->name);
>        printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
> -      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
> -	      " BITS_PER_UNIT);\n", m->name, m->name);
> +      printf ("    if (!multiple_p (mode_precision[E_%smode],"
> +	      " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
> +      printf ("      mode_size[E_%smode] = -1;\n", m->name);
>        printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
>        printf ("    adjust_mode_mask (E_%smode);\n", m->name);
>        printf ("  }\n");
> @@ -1963,6 +1967,24 @@ emit_mode_adjustments (void)
>      printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
>  	    a->file, a->line, a->mode->name, a->adjustment);
>  
> +  /* Adjust precision to the actual bits size.  */
> +  for (a = adj_precision; a; a = a->next)
> +    switch (a->mode->cl)
> +      {
> +	case MODE_VECTOR_BOOL:
> +	  printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
> +		  a->adjustment);
> +	  printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
> +	  break;
> +	default:
> +	  break;

Sorry for not noticing earlier, but I think the default case should be:

	  internal_error ("invalid use of ADJUST_PRECISION");
	  /* NOTREACHED */

so that we don't just silently ignore ADJUST_PRECISIONs.  (No need for
a break afterwards.)

The genmodes.cc part is OK with that change, thanks.

Richard

> +      }
> +
> +  /* Ensure there is no mode size equals -1.  */
> +  for_all_modes (c, m)
> +    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
> +	    m->name, m->name);
> +
>    puts ("}");
>  }
>  
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> new file mode 100644
> index 00000000000..e70960c5b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> new file mode 100644
> index 00000000000..dcc7a644a88
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> new file mode 100644
> index 00000000000..3af0513e006
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> new file mode 100644
> index 00000000000..ea3c360d756
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> new file mode 100644
> index 00000000000..9fc659d2402
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> new file mode 100644
> index 00000000000..98275e5267d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> new file mode 100644
> index 00000000000..8f6f0b11f09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> new file mode 100644
> index 00000000000..d96959dd064
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> @@ -0,0 +1,77 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */

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

* [PATCH v4] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-03  2:31 [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment pan2.li
  2023-03-03  8:06 ` Kito Cheng
  2023-03-06 13:41 ` Richard Sandiford
@ 2023-03-06 14:57 ` pan2.li
  2023-03-06 15:01   ` Richard Sandiford
  2023-03-07 12:05 ` [PATCH v5] " pan2.li
  3 siblings, 1 reply; 10+ messages in thread
From: pan2.li @ 2023-03-06 14:57 UTC (permalink / raw)
  To: gcc-patches
  Cc: juzhe.zhong, kito.cheng, rguenther, pan2.li, richard.sandiford

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

	Fix the bug of the rvv bool mode precision with the adjustment.
	The bits size of vbool*_t will be adjusted to
	[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
	adjusted mode precison of vbool*_t will help underlying pass to
	make the right decision for both the correctness and optimization.

	Given below sample code:
	void test_1(int8_t * restrict in, int8_t * restrict out)
	{
	  vbool8_t v2 = *(vbool8_t*)in;
	  vbool16_t v5 = *(vbool16_t*)in;
	  *(vbool16_t*)(out + 200) = v5;
	  *(vbool8_t*)(out + 100) = v2;
	}

	Before the precision adjustment:
	addi    a4,a1,100
	vsetvli a5,zero,e8,m1,ta,ma
	addi    a1,a1,200
	vlm.v   v24,0(a0)
	vsm.v   v24,0(a4)
	// Need one vsetvli and vlm.v for correctness here.
	vsm.v   v24,0(a1)

	After the precision adjustment:
	csrr    t0,vlenb
	slli    t1,t0,1
	csrr    a3,vlenb
	sub     sp,sp,t1
	slli    a4,a3,1
	add     a4,a4,sp
	sub     a3,a4,a3
	vsetvli a5,zero,e8,m1,ta,ma
	addi    a2,a1,200
	vlm.v   v24,0(a0)
	vsm.v   v24,0(a3)
	addi    a1,a1,100
	vsetvli a4,zero,e8,mf2,ta,ma
	csrr    t0,vlenb
	vlm.v   v25,0(a3)
	vsm.v   v25,0(a2)
	slli    t1,t0,1
	vsetvli a5,zero,e8,m1,ta,ma
	vsm.v   v24,0(a1)
	add     sp,sp,t1
	jr      ra

	However, there may be some optimization opportunates after
	the mode precision adjustment. It can be token care of in
	the RISC-V backend in the underlying separted PR(s).

	PR 108185
	PR 108654

gcc/ChangeLog:

	* config/riscv/riscv-modes.def (ADJUST_PRECISION):
	* config/riscv/riscv.cc (riscv_v_adjust_precision):
	* config/riscv/riscv.h (riscv_v_adjust_precision):
	* genmodes.cc (ADJUST_PRECISION):
	(emit_mode_adjustments):

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/pr108185-1.c: New test.
	* gcc.target/riscv/pr108185-2.c: New test.
	* gcc.target/riscv/pr108185-3.c: New test.
	* gcc.target/riscv/pr108185-4.c: New test.
	* gcc.target/riscv/pr108185-5.c: New test.
	* gcc.target/riscv/pr108185-6.c: New test.
	* gcc.target/riscv/pr108185-7.c: New test.
	* gcc.target/riscv/pr108185-8.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
Co-authored-by: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
---
 gcc/config/riscv/riscv-modes.def            |  8 +++
 gcc/config/riscv/riscv.cc                   | 12 ++++
 gcc/config/riscv/riscv.h                    |  1 +
 gcc/genmodes.cc                             | 28 +++++++-
 gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
 12 files changed, 600 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c

diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
index d5305efa8a6..110bddce851 100644
--- a/gcc/config/riscv/riscv-modes.def
+++ b/gcc/config/riscv/riscv-modes.def
@@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
 ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
 ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
 
+ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1));
+ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2));
+ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4));
+ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8));
+ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16));
+ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32));
+ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64));
+
 /*
    | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
    |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f11b7949a49..ac5c2527fde 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
   return scale;
 }
 
+/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
+   PRECISION size for corresponding machine_mode.  */
+
+poly_int64
+riscv_v_adjust_precision (machine_mode mode, int scale)
+{
+  if (riscv_v_ext_vector_mode_p (mode))
+    return riscv_vector_chunks * scale;
+
+  return scale;
+}
+
 /* Return true if X is a valid address for machine mode MODE.  If it is,
    fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
    effect.  */
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 5bc7f2f467d..15b9317a8ce 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;
 extern unsigned riscv_bytes_per_vector_chunk;
 extern poly_uint16 riscv_vector_chunks;
 extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
+extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
 /* The number of bits and bytes in a RVV vector.  */
 #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
 #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index 2d418f09aab..afc561d5d4c 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;
 static struct mode_adjust *adj_format;
 static struct mode_adjust *adj_ibit;
 static struct mode_adjust *adj_fbit;
+static struct mode_adjust *adj_precision;
 
 /* Mode class operations.  */
 static enum mode_class
@@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
 #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
 #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
 #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
+#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM)
 #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
 #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
 #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
@@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void)
 static void
 emit_mode_adjustments (void)
 {
+  int c;
   struct mode_adjust *a;
   struct mode_data *m;
 
@@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
 	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
 	      m->name, m->name);
       printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
-      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
-	      " BITS_PER_UNIT);\n", m->name, m->name);
+      printf ("    if (!multiple_p (mode_precision[E_%smode],"
+	      " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
+      printf ("      mode_size[E_%smode] = -1;\n", m->name);
       printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
       printf ("    adjust_mode_mask (E_%smode);\n", m->name);
       printf ("  }\n");
@@ -1963,6 +1967,26 @@ emit_mode_adjustments (void)
     printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
 	    a->file, a->line, a->mode->name, a->adjustment);
 
+  /* Adjust precision to the actual bits size.  */
+  for (a = adj_precision; a; a = a->next)
+    switch (a->mode->cl)
+      {
+	case MODE_VECTOR_BOOL:
+	  printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
+		  a->adjustment);
+	  printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
+	  break;
+	default:
+	  internal_error ("invalid use of ADJUST_PRECISION for mode %s",
+			  a->mode->name);
+	  /* NOTREACHED */
+      }
+
+  /* Ensure there is no mode size equals -1.  */
+  for_all_modes (c, m)
+    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
+	    m->name, m->name);
+
   puts ("}");
 }
 
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
new file mode 100644
index 00000000000..e70960c5b6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
new file mode 100644
index 00000000000..dcc7a644a88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
new file mode 100644
index 00000000000..3af0513e006
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
new file mode 100644
index 00000000000..ea3c360d756
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
new file mode 100644
index 00000000000..9fc659d2402
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
new file mode 100644
index 00000000000..98275e5267d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
new file mode 100644
index 00000000000..8f6f0b11f09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
new file mode 100644
index 00000000000..d96959dd064
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
@@ -0,0 +1,77 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
-- 
2.34.1


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

* RE: [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-06 13:41 ` Richard Sandiford
@ 2023-03-06 14:59   ` Li, Pan2
  0 siblings, 0 replies; 10+ messages in thread
From: Li, Pan2 @ 2023-03-06 14:59 UTC (permalink / raw)
  To: Richard Sandiford; +Cc: gcc-patches, juzhe.zhong, kito.cheng, rguenther

Got it and it makes sense to me from the perspective of the defensive programming.

Thanks a lot, and update the PATCH v4 as below link.

https://gcc.gnu.org/pipermail/gcc-patches/2023-March/613465.html

Pan

-----Original Message-----
From: Richard Sandiford <richard.sandiford@arm.com> 
Sent: Monday, March 6, 2023 9:41 PM
To: Li, Pan2 <pan2.li@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; kito.cheng@sifive.com; rguenther@suse.de
Subject: Re: [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment

pan2.li@intel.com writes:
> From: Pan Li <pan2.li@intel.com>
>
> 	Fix the bug of the rvv bool mode precision with the adjustment.
> 	The bits size of vbool*_t will be adjusted to
> 	[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
> 	adjusted mode precison of vbool*_t will help underlying pass to
> 	make the right decision for both the correctness and optimization.
>
> 	Given below sample code:
> 	void test_1(int8_t * restrict in, int8_t * restrict out)
> 	{
> 	  vbool8_t v2 = *(vbool8_t*)in;
> 	  vbool16_t v5 = *(vbool16_t*)in;
> 	  *(vbool16_t*)(out + 200) = v5;
> 	  *(vbool8_t*)(out + 100) = v2;
> 	}
>
> 	Before the precision adjustment:
> 	addi    a4,a1,100
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a1,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a4)
> 	// Need one vsetvli and vlm.v for correctness here.
> 	vsm.v   v24,0(a1)
>
> 	After the precision adjustment:
> 	csrr    t0,vlenb
> 	slli    t1,t0,1
> 	csrr    a3,vlenb
> 	sub     sp,sp,t1
> 	slli    a4,a3,1
> 	add     a4,a4,sp
> 	sub     a3,a4,a3
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a2,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a3)
> 	addi    a1,a1,100
> 	vsetvli a4,zero,e8,mf2,ta,ma
> 	csrr    t0,vlenb
> 	vlm.v   v25,0(a3)
> 	vsm.v   v25,0(a2)
> 	slli    t1,t0,1
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	vsm.v   v24,0(a1)
> 	add     sp,sp,t1
> 	jr      ra
>
> 	However, there may be some optimization opportunates after
> 	the mode precision adjustment. It can be token care of in
> 	the RISC-V backend in the underlying separted PR(s).
>
> 	PR 108185
> 	PR 108654
>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv-modes.def (ADJUST_PRECISION):
> 	* config/riscv/riscv.cc (riscv_v_adjust_precision):
> 	* config/riscv/riscv.h (riscv_v_adjust_precision):
> 	* genmodes.cc (ADJUST_PRECISION):
> 	(emit_mode_adjustments):
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/pr108185-1.c: New test.
> 	* gcc.target/riscv/pr108185-2.c: New test.
> 	* gcc.target/riscv/pr108185-3.c: New test.
> 	* gcc.target/riscv/pr108185-4.c: New test.
> 	* gcc.target/riscv/pr108185-5.c: New test.
> 	* gcc.target/riscv/pr108185-6.c: New test.
> 	* gcc.target/riscv/pr108185-7.c: New test.
> 	* gcc.target/riscv/pr108185-8.c: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> ---
>  gcc/config/riscv/riscv-modes.def            |  8 +++
>  gcc/config/riscv/riscv.cc                   | 12 ++++
>  gcc/config/riscv/riscv.h                    |  1 +
>  gcc/genmodes.cc                             | 26 ++++++-
>  gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
>  12 files changed, 598 insertions(+), 2 deletions(-)  create mode 
> 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c
>
> diff --git a/gcc/config/riscv/riscv-modes.def 
> b/gcc/config/riscv/riscv-modes.def
> index d5305efa8a6..110bddce851 100644
> --- a/gcc/config/riscv/riscv-modes.def
> +++ b/gcc/config/riscv/riscv-modes.def
> @@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * 
> riscv_bytes_per_vector_chunk);  ADJUST_BYTESIZE (VNx32BI, 
> riscv_vector_chunks * riscv_bytes_per_vector_chunk);  ADJUST_BYTESIZE 
> (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
>  
> +ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1)); 
> +ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2)); 
> +ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4)); 
> +ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8)); 
> +ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 
> +16)); ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision 
> +(VNx32BImode, 32)); ADJUST_PRECISION (VNx64BI, 
> +riscv_v_adjust_precision (VNx64BImode, 64));
> +
>  /*
>     | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
>     |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc 
> index f11b7949a49..ac5c2527fde 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
>    return scale;
>  }
>  
> +/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
> +   PRECISION size for corresponding machine_mode.  */
> +
> +poly_int64
> +riscv_v_adjust_precision (machine_mode mode, int scale) {
> +  if (riscv_v_ext_vector_mode_p (mode))
> +    return riscv_vector_chunks * scale;
> +
> +  return scale;
> +}
> +
>  /* Return true if X is a valid address for machine mode MODE.  If it is,
>     fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
>     effect.  */
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 
> 5bc7f2f467d..15b9317a8ce 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;  extern 
> unsigned riscv_bytes_per_vector_chunk;  extern poly_uint16 
> riscv_vector_chunks;  extern poly_int64 riscv_v_adjust_nunits (enum 
> machine_mode, int);
> +extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
>  /* The number of bits and bytes in a RVV vector.  */  #define 
> BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * 
> riscv_bytes_per_vector_chunk * 8))  #define BYTES_PER_RISCV_VECTOR 
> (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk)) 
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc index 
> 2d418f09aab..4b262040ff8 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;  static 
> struct mode_adjust *adj_format;  static struct mode_adjust *adj_ibit;  
> static struct mode_adjust *adj_fbit;
> +static struct mode_adjust *adj_precision;
>  
>  /* Mode class operations.  */
>  static enum mode_class
> @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
>  #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
>  #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, 
> RANDOM)  #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, 
> RANDOM, RANDOM)
> +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, 
> +RANDOM)
>  #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
>  #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)  
> #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM) @@ 
> -1794,6 +1796,7 @@ emit_real_format_for_mode (void)  static void  
> emit_mode_adjustments (void)  {
> +  int c;
>    struct mode_adjust *a;
>    struct mode_data *m;
>  
> @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
>  	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
>  	      m->name, m->name);
>        printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
> -      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
> -	      " BITS_PER_UNIT);\n", m->name, m->name);
> +      printf ("    if (!multiple_p (mode_precision[E_%smode],"
> +	      " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
> +      printf ("      mode_size[E_%smode] = -1;\n", m->name);
>        printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
>        printf ("    adjust_mode_mask (E_%smode);\n", m->name);
>        printf ("  }\n");
> @@ -1963,6 +1967,24 @@ emit_mode_adjustments (void)
>      printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
>  	    a->file, a->line, a->mode->name, a->adjustment);
>  
> +  /* Adjust precision to the actual bits size.  */
> +  for (a = adj_precision; a; a = a->next)
> +    switch (a->mode->cl)
> +      {
> +	case MODE_VECTOR_BOOL:
> +	  printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
> +		  a->adjustment);
> +	  printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
> +	  break;
> +	default:
> +	  break;

Sorry for not noticing earlier, but I think the default case should be:

	  internal_error ("invalid use of ADJUST_PRECISION");
	  /* NOTREACHED */

so that we don't just silently ignore ADJUST_PRECISIONs.  (No need for a break afterwards.)

The genmodes.cc part is OK with that change, thanks.

Richard

> +      }
> +
> +  /* Ensure there is no mode size equals -1.  */
> +  for_all_modes (c, m)
> +    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
> +	    m->name, m->name);
> +
>    puts ("}");
>  }
>  
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> new file mode 100644
> index 00000000000..e70960c5b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> new file mode 100644
> index 00000000000..dcc7a644a88
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> new file mode 100644
> index 00000000000..3af0513e006
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> new file mode 100644
> index 00000000000..ea3c360d756
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> new file mode 100644
> index 00000000000..9fc659d2402
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> new file mode 100644
> index 00000000000..98275e5267d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> new file mode 100644
> index 00000000000..8f6f0b11f09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> new file mode 100644
> index 00000000000..d96959dd064
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> @@ -0,0 +1,77 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */

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

* Re: [PATCH v4] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-06 14:57 ` [PATCH v4] " pan2.li
@ 2023-03-06 15:01   ` Richard Sandiford
  2023-03-07 12:14     ` Li, Pan2
  0 siblings, 1 reply; 10+ messages in thread
From: Richard Sandiford @ 2023-03-06 15:01 UTC (permalink / raw)
  To: pan2.li; +Cc: gcc-patches, juzhe.zhong, kito.cheng, rguenther

pan2.li@intel.com writes:
> From: Pan Li <pan2.li@intel.com>
>
> 	Fix the bug of the rvv bool mode precision with the adjustment.
> 	The bits size of vbool*_t will be adjusted to
> 	[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
> 	adjusted mode precison of vbool*_t will help underlying pass to
> 	make the right decision for both the correctness and optimization.
>
> 	Given below sample code:
> 	void test_1(int8_t * restrict in, int8_t * restrict out)
> 	{
> 	  vbool8_t v2 = *(vbool8_t*)in;
> 	  vbool16_t v5 = *(vbool16_t*)in;
> 	  *(vbool16_t*)(out + 200) = v5;
> 	  *(vbool8_t*)(out + 100) = v2;
> 	}
>
> 	Before the precision adjustment:
> 	addi    a4,a1,100
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a1,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a4)
> 	// Need one vsetvli and vlm.v for correctness here.
> 	vsm.v   v24,0(a1)
>
> 	After the precision adjustment:
> 	csrr    t0,vlenb
> 	slli    t1,t0,1
> 	csrr    a3,vlenb
> 	sub     sp,sp,t1
> 	slli    a4,a3,1
> 	add     a4,a4,sp
> 	sub     a3,a4,a3
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a2,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a3)
> 	addi    a1,a1,100
> 	vsetvli a4,zero,e8,mf2,ta,ma
> 	csrr    t0,vlenb
> 	vlm.v   v25,0(a3)
> 	vsm.v   v25,0(a2)
> 	slli    t1,t0,1
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	vsm.v   v24,0(a1)
> 	add     sp,sp,t1
> 	jr      ra
>
> 	However, there may be some optimization opportunates after
> 	the mode precision adjustment. It can be token care of in
> 	the RISC-V backend in the underlying separted PR(s).
>
> 	PR 108185
> 	PR 108654
>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv-modes.def (ADJUST_PRECISION):
> 	* config/riscv/riscv.cc (riscv_v_adjust_precision):
> 	* config/riscv/riscv.h (riscv_v_adjust_precision):
> 	* genmodes.cc (ADJUST_PRECISION):
> 	(emit_mode_adjustments):

OK for the genmodes.cc part, thanks.

Richard

> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/pr108185-1.c: New test.
> 	* gcc.target/riscv/pr108185-2.c: New test.
> 	* gcc.target/riscv/pr108185-3.c: New test.
> 	* gcc.target/riscv/pr108185-4.c: New test.
> 	* gcc.target/riscv/pr108185-5.c: New test.
> 	* gcc.target/riscv/pr108185-6.c: New test.
> 	* gcc.target/riscv/pr108185-7.c: New test.
> 	* gcc.target/riscv/pr108185-8.c: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> Co-authored-by: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
> ---
>  gcc/config/riscv/riscv-modes.def            |  8 +++
>  gcc/config/riscv/riscv.cc                   | 12 ++++
>  gcc/config/riscv/riscv.h                    |  1 +
>  gcc/genmodes.cc                             | 28 +++++++-
>  gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
>  12 files changed, 600 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c
>
> diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
> index d5305efa8a6..110bddce851 100644
> --- a/gcc/config/riscv/riscv-modes.def
> +++ b/gcc/config/riscv/riscv-modes.def
> @@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
>  
> +ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1));
> +ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2));
> +ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4));
> +ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8));
> +ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16));
> +ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32));
> +ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64));
> +
>  /*
>     | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
>     |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index f11b7949a49..ac5c2527fde 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
>    return scale;
>  }
>  
> +/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
> +   PRECISION size for corresponding machine_mode.  */
> +
> +poly_int64
> +riscv_v_adjust_precision (machine_mode mode, int scale)
> +{
> +  if (riscv_v_ext_vector_mode_p (mode))
> +    return riscv_vector_chunks * scale;
> +
> +  return scale;
> +}
> +
>  /* Return true if X is a valid address for machine mode MODE.  If it is,
>     fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
>     effect.  */
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
> index 5bc7f2f467d..15b9317a8ce 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;
>  extern unsigned riscv_bytes_per_vector_chunk;
>  extern poly_uint16 riscv_vector_chunks;
>  extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
> +extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
>  /* The number of bits and bytes in a RVV vector.  */
>  #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
>  #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
> index 2d418f09aab..afc561d5d4c 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;
>  static struct mode_adjust *adj_format;
>  static struct mode_adjust *adj_ibit;
>  static struct mode_adjust *adj_fbit;
> +static struct mode_adjust *adj_precision;
>  
>  /* Mode class operations.  */
>  static enum mode_class
> @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
>  #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
>  #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
>  #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
> +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM)
>  #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
>  #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
>  #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
> @@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void)
>  static void
>  emit_mode_adjustments (void)
>  {
> +  int c;
>    struct mode_adjust *a;
>    struct mode_data *m;
>  
> @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
>  	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
>  	      m->name, m->name);
>        printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
> -      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
> -	      " BITS_PER_UNIT);\n", m->name, m->name);
> +      printf ("    if (!multiple_p (mode_precision[E_%smode],"
> +	      " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
> +      printf ("      mode_size[E_%smode] = -1;\n", m->name);
>        printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
>        printf ("    adjust_mode_mask (E_%smode);\n", m->name);
>        printf ("  }\n");
> @@ -1963,6 +1967,26 @@ emit_mode_adjustments (void)
>      printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
>  	    a->file, a->line, a->mode->name, a->adjustment);
>  
> +  /* Adjust precision to the actual bits size.  */
> +  for (a = adj_precision; a; a = a->next)
> +    switch (a->mode->cl)
> +      {
> +	case MODE_VECTOR_BOOL:
> +	  printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
> +		  a->adjustment);
> +	  printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
> +	  break;
> +	default:
> +	  internal_error ("invalid use of ADJUST_PRECISION for mode %s",
> +			  a->mode->name);
> +	  /* NOTREACHED */
> +      }
> +
> +  /* Ensure there is no mode size equals -1.  */
> +  for_all_modes (c, m)
> +    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
> +	    m->name, m->name);
> +
>    puts ("}");
>  }
>  
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> new file mode 100644
> index 00000000000..e70960c5b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> new file mode 100644
> index 00000000000..dcc7a644a88
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> new file mode 100644
> index 00000000000..3af0513e006
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> new file mode 100644
> index 00000000000..ea3c360d756
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> new file mode 100644
> index 00000000000..9fc659d2402
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> new file mode 100644
> index 00000000000..98275e5267d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> new file mode 100644
> index 00000000000..8f6f0b11f09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> new file mode 100644
> index 00000000000..d96959dd064
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> @@ -0,0 +1,77 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */

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

* [PATCH v5] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-03  2:31 [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment pan2.li
                   ` (2 preceding siblings ...)
  2023-03-06 14:57 ` [PATCH v4] " pan2.li
@ 2023-03-07 12:05 ` pan2.li
  2023-03-07 13:45   ` Kito Cheng
  3 siblings, 1 reply; 10+ messages in thread
From: pan2.li @ 2023-03-07 12:05 UTC (permalink / raw)
  To: gcc-patches
  Cc: juzhe.zhong, kito.cheng, rguenther, pan2.li, richard.sandiford

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

	Fix the bug of the rvv bool mode precision with the adjustment.
	The bits size of vbool*_t will be adjusted to
	[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
	adjusted mode precison of vbool*_t will help underlying pass to
	make the right decision for both the correctness and optimization.

	Given below sample code:
	void test_1(int8_t * restrict in, int8_t * restrict out)
	{
	  vbool8_t v2 = *(vbool8_t*)in;
	  vbool16_t v5 = *(vbool16_t*)in;
	  *(vbool16_t*)(out + 200) = v5;
	  *(vbool8_t*)(out + 100) = v2;
	}

	Before the precision adjustment:
	addi    a4,a1,100
	vsetvli a5,zero,e8,m1,ta,ma
	addi    a1,a1,200
	vlm.v   v24,0(a0)
	vsm.v   v24,0(a4)
	// Need one vsetvli and vlm.v for correctness here.
	vsm.v   v24,0(a1)

	After the precision adjustment:
	csrr    t0,vlenb
	slli    t1,t0,1
	csrr    a3,vlenb
	sub     sp,sp,t1
	slli    a4,a3,1
	add     a4,a4,sp
	sub     a3,a4,a3
	vsetvli a5,zero,e8,m1,ta,ma
	addi    a2,a1,200
	vlm.v   v24,0(a0)
	vsm.v   v24,0(a3)
	addi    a1,a1,100
	vsetvli a4,zero,e8,mf2,ta,ma
	csrr    t0,vlenb
	vlm.v   v25,0(a3)
	vsm.v   v25,0(a2)
	slli    t1,t0,1
	vsetvli a5,zero,e8,m1,ta,ma
	vsm.v   v24,0(a1)
	add     sp,sp,t1
	jr      ra

	However, there may be some optimization opportunates after
	the mode precision adjustment. It can be token care of in
	the RISC-V backend in the underlying separted PR(s).

	PR 108185
	PR 108654

gcc/ChangeLog:

	* config/riscv/riscv-modes.def (ADJUST_PRECISION):
	* config/riscv/riscv.cc (riscv_v_adjust_precision):
	* config/riscv/riscv.h (riscv_v_adjust_precision):
	* genmodes.cc (ADJUST_PRECISION):
	(emit_mode_adjustments):

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/pr108185-1.c: New test.
	* gcc.target/riscv/pr108185-2.c: New test.
	* gcc.target/riscv/pr108185-3.c: New test.
	* gcc.target/riscv/pr108185-4.c: New test.
	* gcc.target/riscv/pr108185-5.c: New test.
	* gcc.target/riscv/pr108185-6.c: New test.
	* gcc.target/riscv/pr108185-7.c: New test.
	* gcc.target/riscv/pr108185-8.c: New test.

Signed-off-by: Pan Li <pan2.li@intel.com>
Co-authored-by: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
---
 gcc/config/riscv/riscv-modes.def            |  8 +++
 gcc/config/riscv/riscv.cc                   | 12 ++++
 gcc/config/riscv/riscv.h                    |  1 +
 gcc/genmodes.cc                             | 28 +++++++-
 gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
 12 files changed, 600 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c

diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
index d5305efa8a6..110bddce851 100644
--- a/gcc/config/riscv/riscv-modes.def
+++ b/gcc/config/riscv/riscv-modes.def
@@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
 ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
 ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
 
+ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1));
+ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2));
+ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4));
+ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8));
+ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16));
+ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32));
+ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64));
+
 /*
    | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
    |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f11b7949a49..ac5c2527fde 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
   return scale;
 }
 
+/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
+   PRECISION size for corresponding machine_mode.  */
+
+poly_int64
+riscv_v_adjust_precision (machine_mode mode, int scale)
+{
+  if (riscv_v_ext_vector_mode_p (mode))
+    return riscv_vector_chunks * scale;
+
+  return scale;
+}
+
 /* Return true if X is a valid address for machine mode MODE.  If it is,
    fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
    effect.  */
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 5bc7f2f467d..15b9317a8ce 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;
 extern unsigned riscv_bytes_per_vector_chunk;
 extern poly_uint16 riscv_vector_chunks;
 extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
+extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
 /* The number of bits and bytes in a RVV vector.  */
 #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
 #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index 2d418f09aab..715787b8f48 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;
 static struct mode_adjust *adj_format;
 static struct mode_adjust *adj_ibit;
 static struct mode_adjust *adj_fbit;
+static struct mode_adjust *adj_precision;
 
 /* Mode class operations.  */
 static enum mode_class
@@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
 #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
 #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
 #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
+#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM)
 #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
 #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
 #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
@@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void)
 static void
 emit_mode_adjustments (void)
 {
+  int c;
   struct mode_adjust *a;
   struct mode_data *m;
 
@@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
 	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
 	      m->name, m->name);
       printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
-      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
-	      " BITS_PER_UNIT);\n", m->name, m->name);
+      printf ("    if (!multiple_p (mode_precision[E_%smode],"
+	      " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
+      printf ("      mode_size[E_%smode] = -1;\n", m->name);
       printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
       printf ("    adjust_mode_mask (E_%smode);\n", m->name);
       printf ("  }\n");
@@ -1963,6 +1967,26 @@ emit_mode_adjustments (void)
     printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
 	    a->file, a->line, a->mode->name, a->adjustment);
 
+  /* Adjust precision to the actual bits size.  */
+  for (a = adj_precision; a; a = a->next)
+    switch (a->mode->cl)
+      {
+	case MODE_VECTOR_BOOL:
+	  printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
+		  a->adjustment);
+	  printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
+	  break;
+	default:
+	  internal_error ("invalid use of ADJUST_PRECISION for mode %s",
+			  a->mode->name);
+	  /* NOTREACHED.  */
+      }
+
+  /* Ensure there is no mode size equals -1.  */
+  for_all_modes (c, m)
+    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
+	    m->name);
+
   puts ("}");
 }
 
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
new file mode 100644
index 00000000000..e70960c5b6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
new file mode 100644
index 00000000000..dcc7a644a88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
new file mode 100644
index 00000000000..3af0513e006
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
new file mode 100644
index 00000000000..ea3c360d756
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
new file mode 100644
index 00000000000..9fc659d2402
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
new file mode 100644
index 00000000000..98275e5267d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
new file mode 100644
index 00000000000..8f6f0b11f09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
new file mode 100644
index 00000000000..d96959dd064
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
@@ -0,0 +1,77 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
+
+#include "riscv_vector.h"
+
+void
+test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
+    vbool1_t v1 = *(vbool1_t*)in;
+    vbool1_t v2 = *(vbool1_t*)in;
+
+    *(vbool1_t*)(out + 100) = v1;
+    *(vbool1_t*)(out + 200) = v2;
+}
+
+void
+test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
+    vbool2_t v1 = *(vbool2_t*)in;
+    vbool2_t v2 = *(vbool2_t*)in;
+
+    *(vbool2_t*)(out + 100) = v1;
+    *(vbool2_t*)(out + 200) = v2;
+}
+
+void
+test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
+    vbool4_t v1 = *(vbool4_t*)in;
+    vbool4_t v2 = *(vbool4_t*)in;
+
+    *(vbool4_t*)(out + 100) = v1;
+    *(vbool4_t*)(out + 200) = v2;
+}
+
+void
+test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
+    vbool8_t v1 = *(vbool8_t*)in;
+    vbool8_t v2 = *(vbool8_t*)in;
+
+    *(vbool8_t*)(out + 100) = v1;
+    *(vbool8_t*)(out + 200) = v2;
+}
+
+void
+test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
+    vbool16_t v1 = *(vbool16_t*)in;
+    vbool16_t v2 = *(vbool16_t*)in;
+
+    *(vbool16_t*)(out + 100) = v1;
+    *(vbool16_t*)(out + 200) = v2;
+}
+
+void
+test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
+    vbool32_t v1 = *(vbool32_t*)in;
+    vbool32_t v2 = *(vbool32_t*)in;
+
+    *(vbool32_t*)(out + 100) = v1;
+    *(vbool32_t*)(out + 200) = v2;
+}
+
+void
+test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
+    vbool64_t v1 = *(vbool64_t*)in;
+    vbool64_t v2 = *(vbool64_t*)in;
+
+    *(vbool64_t*)(out + 100) = v1;
+    *(vbool64_t*)(out + 200) = v2;
+}
+
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
+/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
+/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
-- 
2.34.1


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

* RE: [PATCH v4] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-06 15:01   ` Richard Sandiford
@ 2023-03-07 12:14     ` Li, Pan2
  0 siblings, 0 replies; 10+ messages in thread
From: Li, Pan2 @ 2023-03-07 12:14 UTC (permalink / raw)
  To: gcc-patches
  Cc: gcc-patches, juzhe.zhong, kito.cheng, rguenther, Richard Sandiford

Great! Thank you very much for help, Richard Sandiford!

Just adjusted the PATCH v5 with minor changes for the GNU style check, and completed the regression test and the RISC-V backend test without any surprise.
Given that is there anyone can help to merge this PATCH? Any question or concern please help to let me know.

https://gcc.gnu.org/pipermail/gcc-patches/2023-March/613504.html

Pan

-----Original Message-----
From: Richard Sandiford <richard.sandiford@arm.com> 
Sent: Monday, March 6, 2023 11:02 PM
To: Li, Pan2 <pan2.li@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zhong@rivai.ai; kito.cheng@sifive.com; rguenther@suse.de
Subject: Re: [PATCH v4] RISC-V: Bugfix for rvv bool mode precision adjustment

pan2.li@intel.com writes:
> From: Pan Li <pan2.li@intel.com>
>
> 	Fix the bug of the rvv bool mode precision with the adjustment.
> 	The bits size of vbool*_t will be adjusted to
> 	[1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
> 	adjusted mode precison of vbool*_t will help underlying pass to
> 	make the right decision for both the correctness and optimization.
>
> 	Given below sample code:
> 	void test_1(int8_t * restrict in, int8_t * restrict out)
> 	{
> 	  vbool8_t v2 = *(vbool8_t*)in;
> 	  vbool16_t v5 = *(vbool16_t*)in;
> 	  *(vbool16_t*)(out + 200) = v5;
> 	  *(vbool8_t*)(out + 100) = v2;
> 	}
>
> 	Before the precision adjustment:
> 	addi    a4,a1,100
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a1,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a4)
> 	// Need one vsetvli and vlm.v for correctness here.
> 	vsm.v   v24,0(a1)
>
> 	After the precision adjustment:
> 	csrr    t0,vlenb
> 	slli    t1,t0,1
> 	csrr    a3,vlenb
> 	sub     sp,sp,t1
> 	slli    a4,a3,1
> 	add     a4,a4,sp
> 	sub     a3,a4,a3
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	addi    a2,a1,200
> 	vlm.v   v24,0(a0)
> 	vsm.v   v24,0(a3)
> 	addi    a1,a1,100
> 	vsetvli a4,zero,e8,mf2,ta,ma
> 	csrr    t0,vlenb
> 	vlm.v   v25,0(a3)
> 	vsm.v   v25,0(a2)
> 	slli    t1,t0,1
> 	vsetvli a5,zero,e8,m1,ta,ma
> 	vsm.v   v24,0(a1)
> 	add     sp,sp,t1
> 	jr      ra
>
> 	However, there may be some optimization opportunates after
> 	the mode precision adjustment. It can be token care of in
> 	the RISC-V backend in the underlying separted PR(s).
>
> 	PR 108185
> 	PR 108654
>
> gcc/ChangeLog:
>
> 	* config/riscv/riscv-modes.def (ADJUST_PRECISION):
> 	* config/riscv/riscv.cc (riscv_v_adjust_precision):
> 	* config/riscv/riscv.h (riscv_v_adjust_precision):
> 	* genmodes.cc (ADJUST_PRECISION):
> 	(emit_mode_adjustments):

OK for the genmodes.cc part, thanks.

Richard

> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/riscv/pr108185-1.c: New test.
> 	* gcc.target/riscv/pr108185-2.c: New test.
> 	* gcc.target/riscv/pr108185-3.c: New test.
> 	* gcc.target/riscv/pr108185-4.c: New test.
> 	* gcc.target/riscv/pr108185-5.c: New test.
> 	* gcc.target/riscv/pr108185-6.c: New test.
> 	* gcc.target/riscv/pr108185-7.c: New test.
> 	* gcc.target/riscv/pr108185-8.c: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> Co-authored-by: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
> ---
>  gcc/config/riscv/riscv-modes.def            |  8 +++
>  gcc/config/riscv/riscv.cc                   | 12 ++++
>  gcc/config/riscv/riscv.h                    |  1 +
>  gcc/genmodes.cc                             | 28 +++++++-
>  gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++  
> gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
>  12 files changed, 600 insertions(+), 2 deletions(-)  create mode 
> 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c
>
> diff --git a/gcc/config/riscv/riscv-modes.def 
> b/gcc/config/riscv/riscv-modes.def
> index d5305efa8a6..110bddce851 100644
> --- a/gcc/config/riscv/riscv-modes.def
> +++ b/gcc/config/riscv/riscv-modes.def
> @@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * 
> riscv_bytes_per_vector_chunk);  ADJUST_BYTESIZE (VNx32BI, 
> riscv_vector_chunks * riscv_bytes_per_vector_chunk);  ADJUST_BYTESIZE 
> (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
>  
> +ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1)); 
> +ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2)); 
> +ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4)); 
> +ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8)); 
> +ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 
> +16)); ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision 
> +(VNx32BImode, 32)); ADJUST_PRECISION (VNx64BI, 
> +riscv_v_adjust_precision (VNx64BImode, 64));
> +
>  /*
>     | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
>     |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc 
> index f11b7949a49..ac5c2527fde 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
>    return scale;
>  }
>  
> +/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
> +   PRECISION size for corresponding machine_mode.  */
> +
> +poly_int64
> +riscv_v_adjust_precision (machine_mode mode, int scale) {
> +  if (riscv_v_ext_vector_mode_p (mode))
> +    return riscv_vector_chunks * scale;
> +
> +  return scale;
> +}
> +
>  /* Return true if X is a valid address for machine mode MODE.  If it is,
>     fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
>     effect.  */
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 
> 5bc7f2f467d..15b9317a8ce 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;  extern 
> unsigned riscv_bytes_per_vector_chunk;  extern poly_uint16 
> riscv_vector_chunks;  extern poly_int64 riscv_v_adjust_nunits (enum 
> machine_mode, int);
> +extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
>  /* The number of bits and bytes in a RVV vector.  */  #define 
> BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * 
> riscv_bytes_per_vector_chunk * 8))  #define BYTES_PER_RISCV_VECTOR 
> (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk)) 
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc index 
> 2d418f09aab..afc561d5d4c 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;  static 
> struct mode_adjust *adj_format;  static struct mode_adjust *adj_ibit;  
> static struct mode_adjust *adj_fbit;
> +static struct mode_adjust *adj_precision;
>  
>  /* Mode class operations.  */
>  static enum mode_class
> @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
>  #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
>  #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, 
> RANDOM)  #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, 
> RANDOM, RANDOM)
> +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, 
> +RANDOM)
>  #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
>  #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)  
> #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM) @@ 
> -1794,6 +1796,7 @@ emit_real_format_for_mode (void)  static void  
> emit_mode_adjustments (void)  {
> +  int c;
>    struct mode_adjust *a;
>    struct mode_data *m;
>  
> @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
>  	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
>  	      m->name, m->name);
>        printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
> -      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
> -	      " BITS_PER_UNIT);\n", m->name, m->name);
> +      printf ("    if (!multiple_p (mode_precision[E_%smode],"
> +	      " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
> +      printf ("      mode_size[E_%smode] = -1;\n", m->name);
>        printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
>        printf ("    adjust_mode_mask (E_%smode);\n", m->name);
>        printf ("  }\n");
> @@ -1963,6 +1967,26 @@ emit_mode_adjustments (void)
>      printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
>  	    a->file, a->line, a->mode->name, a->adjustment);
>  
> +  /* Adjust precision to the actual bits size.  */
> +  for (a = adj_precision; a; a = a->next)
> +    switch (a->mode->cl)
> +      {
> +	case MODE_VECTOR_BOOL:
> +	  printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
> +		  a->adjustment);
> +	  printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
> +	  break;
> +	default:
> +	  internal_error ("invalid use of ADJUST_PRECISION for mode %s",
> +			  a->mode->name);
> +	  /* NOTREACHED */
> +      }
> +
> +  /* Ensure there is no mode size equals -1.  */
> +  for_all_modes (c, m)
> +    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
> +	    m->name, m->name);
> +
>    puts ("}");
>  }
>  
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> new file mode 100644
> index 00000000000..e70960c5b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> new file mode 100644
> index 00000000000..dcc7a644a88
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> new file mode 100644
> index 00000000000..3af0513e006
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> new file mode 100644
> index 00000000000..ea3c360d756
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> new file mode 100644
> index 00000000000..9fc659d2402
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> new file mode 100644
> index 00000000000..98275e5267d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> new file mode 100644
> index 00000000000..8f6f0b11f09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c 
> b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> new file mode 100644
> index 00000000000..d96959dd064
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> @@ -0,0 +1,77 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times 
> +{vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
> +/* { dg-final { scan-assembler-times 
> +{vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */

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

* Re: [PATCH v5] RISC-V: Bugfix for rvv bool mode precision adjustment
  2023-03-07 12:05 ` [PATCH v5] " pan2.li
@ 2023-03-07 13:45   ` Kito Cheng
  0 siblings, 0 replies; 10+ messages in thread
From: Kito Cheng @ 2023-03-07 13:45 UTC (permalink / raw)
  To: Li, Pan2
  Cc: GCC Patches, 钟居哲,
	Kito Cheng, Richard Biener, richard.sandiford

Hi Pan:

Really appreciate your patch for fixing this issue!

committed to trunk with minor commit log tweak :)

On Tue, Mar 7, 2023 at 8:05 PM pan2.li--- via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Pan Li <pan2.li@intel.com>
>
>         Fix the bug of the rvv bool mode precision with the adjustment.
>         The bits size of vbool*_t will be adjusted to
>         [1, 2, 4, 8, 16, 32, 64] according to the rvv spec 1.0 isa. The
>         adjusted mode precison of vbool*_t will help underlying pass to
>         make the right decision for both the correctness and optimization.
>
>         Given below sample code:
>         void test_1(int8_t * restrict in, int8_t * restrict out)
>         {
>           vbool8_t v2 = *(vbool8_t*)in;
>           vbool16_t v5 = *(vbool16_t*)in;
>           *(vbool16_t*)(out + 200) = v5;
>           *(vbool8_t*)(out + 100) = v2;
>         }
>
>         Before the precision adjustment:
>         addi    a4,a1,100
>         vsetvli a5,zero,e8,m1,ta,ma
>         addi    a1,a1,200
>         vlm.v   v24,0(a0)
>         vsm.v   v24,0(a4)
>         // Need one vsetvli and vlm.v for correctness here.
>         vsm.v   v24,0(a1)
>
>         After the precision adjustment:
>         csrr    t0,vlenb
>         slli    t1,t0,1
>         csrr    a3,vlenb
>         sub     sp,sp,t1
>         slli    a4,a3,1
>         add     a4,a4,sp
>         sub     a3,a4,a3
>         vsetvli a5,zero,e8,m1,ta,ma
>         addi    a2,a1,200
>         vlm.v   v24,0(a0)
>         vsm.v   v24,0(a3)
>         addi    a1,a1,100
>         vsetvli a4,zero,e8,mf2,ta,ma
>         csrr    t0,vlenb
>         vlm.v   v25,0(a3)
>         vsm.v   v25,0(a2)
>         slli    t1,t0,1
>         vsetvli a5,zero,e8,m1,ta,ma
>         vsm.v   v24,0(a1)
>         add     sp,sp,t1
>         jr      ra
>
>         However, there may be some optimization opportunates after
>         the mode precision adjustment. It can be token care of in
>         the RISC-V backend in the underlying separted PR(s).
>
>         PR 108185
>         PR 108654
>
> gcc/ChangeLog:
>
>         * config/riscv/riscv-modes.def (ADJUST_PRECISION):
>         * config/riscv/riscv.cc (riscv_v_adjust_precision):
>         * config/riscv/riscv.h (riscv_v_adjust_precision):
>         * genmodes.cc (ADJUST_PRECISION):
>         (emit_mode_adjustments):
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/pr108185-1.c: New test.
>         * gcc.target/riscv/pr108185-2.c: New test.
>         * gcc.target/riscv/pr108185-3.c: New test.
>         * gcc.target/riscv/pr108185-4.c: New test.
>         * gcc.target/riscv/pr108185-5.c: New test.
>         * gcc.target/riscv/pr108185-6.c: New test.
>         * gcc.target/riscv/pr108185-7.c: New test.
>         * gcc.target/riscv/pr108185-8.c: New test.
>
> Signed-off-by: Pan Li <pan2.li@intel.com>
> Co-authored-by: Ju-Zhe Zhong <juzhe.zhong@rivai.ai>
> ---
>  gcc/config/riscv/riscv-modes.def            |  8 +++
>  gcc/config/riscv/riscv.cc                   | 12 ++++
>  gcc/config/riscv/riscv.h                    |  1 +
>  gcc/genmodes.cc                             | 28 +++++++-
>  gcc/testsuite/gcc.target/riscv/pr108185-1.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-2.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-3.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-4.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-5.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-6.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-7.c | 68 ++++++++++++++++++
>  gcc/testsuite/gcc.target/riscv/pr108185-8.c | 77 +++++++++++++++++++++
>  12 files changed, 600 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-1.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-2.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-3.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-4.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-5.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-6.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-7.c
>  create mode 100644 gcc/testsuite/gcc.target/riscv/pr108185-8.c
>
> diff --git a/gcc/config/riscv/riscv-modes.def b/gcc/config/riscv/riscv-modes.def
> index d5305efa8a6..110bddce851 100644
> --- a/gcc/config/riscv/riscv-modes.def
> +++ b/gcc/config/riscv/riscv-modes.def
> @@ -72,6 +72,14 @@ ADJUST_BYTESIZE (VNx16BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx32BI, riscv_vector_chunks * riscv_bytes_per_vector_chunk);
>  ADJUST_BYTESIZE (VNx64BI, riscv_v_adjust_nunits (VNx64BImode, 8));
>
> +ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1));
> +ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2));
> +ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4));
> +ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8));
> +ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16));
> +ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32));
> +ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64));
> +
>  /*
>     | Mode        | MIN_VLEN=32 | MIN_VLEN=32 | MIN_VLEN=64 | MIN_VLEN=64 |
>     |             | LMUL        | SEW/LMUL    | LMUL        | SEW/LMUL    |
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index f11b7949a49..ac5c2527fde 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -1003,6 +1003,18 @@ riscv_v_adjust_nunits (machine_mode mode, int scale)
>    return scale;
>  }
>
> +/* Call from ADJUST_PRECISION in riscv-modes.def.  Return the correct
> +   PRECISION size for corresponding machine_mode.  */
> +
> +poly_int64
> +riscv_v_adjust_precision (machine_mode mode, int scale)
> +{
> +  if (riscv_v_ext_vector_mode_p (mode))
> +    return riscv_vector_chunks * scale;
> +
> +  return scale;
> +}
> +
>  /* Return true if X is a valid address for machine mode MODE.  If it is,
>     fill in INFO appropriately.  STRICT_P is true if REG_OK_STRICT is in
>     effect.  */
> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
> index 5bc7f2f467d..15b9317a8ce 100644
> --- a/gcc/config/riscv/riscv.h
> +++ b/gcc/config/riscv/riscv.h
> @@ -1025,6 +1025,7 @@ extern unsigned riscv_stack_boundary;
>  extern unsigned riscv_bytes_per_vector_chunk;
>  extern poly_uint16 riscv_vector_chunks;
>  extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
> +extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
>  /* The number of bits and bytes in a RVV vector.  */
>  #define BITS_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk * 8))
>  #define BYTES_PER_RISCV_VECTOR (poly_uint16 (riscv_vector_chunks * riscv_bytes_per_vector_chunk))
> diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
> index 2d418f09aab..715787b8f48 100644
> --- a/gcc/genmodes.cc
> +++ b/gcc/genmodes.cc
> @@ -114,6 +114,7 @@ static struct mode_adjust *adj_alignment;
>  static struct mode_adjust *adj_format;
>  static struct mode_adjust *adj_ibit;
>  static struct mode_adjust *adj_fbit;
> +static struct mode_adjust *adj_precision;
>
>  /* Mode class operations.  */
>  static enum mode_class
> @@ -819,6 +820,7 @@ make_vector_mode (enum mode_class bclass,
>  #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
>  #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
>  #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
> +#define ADJUST_PRECISION(M, X) _ADD_ADJUST (precision, M, X, RANDOM, RANDOM)
>  #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
>  #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
>  #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
> @@ -1794,6 +1796,7 @@ emit_real_format_for_mode (void)
>  static void
>  emit_mode_adjustments (void)
>  {
> +  int c;
>    struct mode_adjust *a;
>    struct mode_data *m;
>
> @@ -1829,8 +1832,9 @@ emit_mode_adjustments (void)
>               " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
>               m->name, m->name);
>        printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
> -      printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
> -             " BITS_PER_UNIT);\n", m->name, m->name);
> +      printf ("    if (!multiple_p (mode_precision[E_%smode],"
> +             " BITS_PER_UNIT, &mode_size[E_%smode]))\n", m->name, m->name);
> +      printf ("      mode_size[E_%smode] = -1;\n", m->name);
>        printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
>        printf ("    adjust_mode_mask (E_%smode);\n", m->name);
>        printf ("  }\n");
> @@ -1963,6 +1967,26 @@ emit_mode_adjustments (void)
>      printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
>             a->file, a->line, a->mode->name, a->adjustment);
>
> +  /* Adjust precision to the actual bits size.  */
> +  for (a = adj_precision; a; a = a->next)
> +    switch (a->mode->cl)
> +      {
> +       case MODE_VECTOR_BOOL:
> +         printf ("\n  /* %s:%d.  */\n  ps = %s;\n", a->file, a->line,
> +                 a->adjustment);
> +         printf ("  mode_precision[E_%smode] = ps;\n", a->mode->name);
> +         break;
> +       default:
> +         internal_error ("invalid use of ADJUST_PRECISION for mode %s",
> +                         a->mode->name);
> +         /* NOTREACHED.  */
> +      }
> +
> +  /* Ensure there is no mode size equals -1.  */
> +  for_all_modes (c, m)
> +    printf ("\n  gcc_assert (maybe_ne (mode_size[E_%smode], -1));\n",
> +           m->name);
> +
>    puts ("}");
>  }
>
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-1.c b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> new file mode 100644
> index 00000000000..e70960c5b6d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-1.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool1_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 18 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-2.c b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> new file mode 100644
> index 00000000000..dcc7a644a88
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-2.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool2_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 17 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-3.c b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> new file mode 100644
> index 00000000000..3af0513e006
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-3.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool4_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 16 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-4.c b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> new file mode 100644
> index 00000000000..ea3c360d756
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-4.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool8_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 15 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-5.c b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> new file mode 100644
> index 00000000000..9fc659d2402
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-5.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool16_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-6.c b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> new file mode 100644
> index 00000000000..98275e5267d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-6.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool32_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 13 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-7.c b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> new file mode 100644
> index 00000000000..8f6f0b11f09
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-7.c
> @@ -0,0 +1,68 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool64_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 6 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 12 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/pr108185-8.c b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> new file mode 100644
> index 00000000000..d96959dd064
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/pr108185-8.c
> @@ -0,0 +1,77 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3" } */
> +
> +#include "riscv_vector.h"
> +
> +void
> +test_vbool1_then_vbool1(int8_t * restrict in, int8_t * restrict out) {
> +    vbool1_t v1 = *(vbool1_t*)in;
> +    vbool1_t v2 = *(vbool1_t*)in;
> +
> +    *(vbool1_t*)(out + 100) = v1;
> +    *(vbool1_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool2_then_vbool2(int8_t * restrict in, int8_t * restrict out) {
> +    vbool2_t v1 = *(vbool2_t*)in;
> +    vbool2_t v2 = *(vbool2_t*)in;
> +
> +    *(vbool2_t*)(out + 100) = v1;
> +    *(vbool2_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool4_then_vbool4(int8_t * restrict in, int8_t * restrict out) {
> +    vbool4_t v1 = *(vbool4_t*)in;
> +    vbool4_t v2 = *(vbool4_t*)in;
> +
> +    *(vbool4_t*)(out + 100) = v1;
> +    *(vbool4_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool8_then_vbool8(int8_t * restrict in, int8_t * restrict out) {
> +    vbool8_t v1 = *(vbool8_t*)in;
> +    vbool8_t v2 = *(vbool8_t*)in;
> +
> +    *(vbool8_t*)(out + 100) = v1;
> +    *(vbool8_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool16_then_vbool16(int8_t * restrict in, int8_t * restrict out) {
> +    vbool16_t v1 = *(vbool16_t*)in;
> +    vbool16_t v2 = *(vbool16_t*)in;
> +
> +    *(vbool16_t*)(out + 100) = v1;
> +    *(vbool16_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool32_then_vbool32(int8_t * restrict in, int8_t * restrict out) {
> +    vbool32_t v1 = *(vbool32_t*)in;
> +    vbool32_t v2 = *(vbool32_t*)in;
> +
> +    *(vbool32_t*)(out + 100) = v1;
> +    *(vbool32_t*)(out + 200) = v2;
> +}
> +
> +void
> +test_vbool64_then_vbool64(int8_t * restrict in, int8_t * restrict out) {
> +    vbool64_t v1 = *(vbool64_t*)in;
> +    vbool64_t v2 = *(vbool64_t*)in;
> +
> +    *(vbool64_t*)(out + 100) = v1;
> +    *(vbool64_t*)(out + 200) = v2;
> +}
> +
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*m1,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf2,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf4,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x][0-9]+,\s*zero,\s*e8,\s*mf8,\s*ta,\s*ma} 1 } } */
> +/* { dg-final { scan-assembler-times {vlm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 7 } } */
> +/* { dg-final { scan-assembler-times {vsm\.v\s+v[0-9]+,\s*0\([a-x][0-9]+\)} 14 } } */
> --
> 2.34.1
>

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

end of thread, other threads:[~2023-03-07 13:46 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-03  2:31 [PATCH v3] RISC-V: Bugfix for rvv bool mode precision adjustment pan2.li
2023-03-03  8:06 ` Kito Cheng
2023-03-06 10:12   ` Li, Pan2
2023-03-06 13:41 ` Richard Sandiford
2023-03-06 14:59   ` Li, Pan2
2023-03-06 14:57 ` [PATCH v4] " pan2.li
2023-03-06 15:01   ` Richard Sandiford
2023-03-07 12:14     ` Li, Pan2
2023-03-07 12:05 ` [PATCH v5] " pan2.li
2023-03-07 13:45   ` Kito Cheng

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).