[gcc r17-3248] RISC-V: Add test cases for vwmaccu.vv reg overlap

Pan Li via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:4f75092d25c099363892d03cb50b1142fb20bdcc

commit r17-3248-g4f75092d25c099363892d03cb50b1142fb20bdcc
Author: Pan Li <[email protected]>
Date:   Wed Aug 12 10:42:29 2026 +0800

    RISC-V: Add test cases for vwmaccu.vv reg overlap
    
    Add test cases for register group overlap, please
    note it is not overlap as much as possible.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m1.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m2.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m4.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf2.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf4.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m1.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m2.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m4.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-mf2.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m1.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m2.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m4.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf2.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf4.c: New test.
            * gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf8.c: New test.
    
    Signed-off-by: Pan Li <[email protected]>

Diff:
---
 .../rvv/autovec/group_overlap/vwmaccu_vv-u16-m1.c  | 57 ++++++++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u16-m2.c  | 49 +++++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u16-m4.c  | 45 +++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u16-mf2.c | 21 ++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u16-mf4.c | 21 ++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u32-m1.c  | 57 ++++++++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u32-m2.c  | 49 +++++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u32-m4.c  | 45 +++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u32-mf2.c | 21 ++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u8-m1.c   | 57 ++++++++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u8-m2.c   | 49 +++++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u8-m4.c   | 45 +++++++++++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u8-mf2.c  | 21 ++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u8-mf4.c  | 21 ++++++++
 .../rvv/autovec/group_overlap/vwmaccu_vv-u8-mf8.c  | 21 ++++++++
 15 files changed, 579 insertions(+)

diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m1.c
new file mode 100644
index 000000000000..b0db1a9fecc3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e16m1,
+  vuint16m1_t,
+  vuint32m2_t,
+  __riscv_vle16_v_u16m1,
+  __riscv_vle32_v_u32m2,
+  __riscv_vwmaccu_vv_u32m2,
+  __riscv_vse32_v_u32m2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e16m1,
+  vuint16m1_t,
+  vuint32m2_t,
+  vuint16m2_t,
+  __riscv_vle16_v_u16m1,
+  __riscv_vle32_v_u32m2,
+  __riscv_vreinterpret_v_u32m2_u16m2,
+  __riscv_vget_v_u16m2_u16m1,
+  __riscv_vwmaccu_vv_u32m2,
+  __riscv_vse32_v_u32m2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v12,v30,v29([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v16,v15([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v0,v31([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v14,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v30,v28,v27([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v28,v26,v25([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v6,v20,v19([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v26,v24,v23([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v18,v17([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v10,v1,v15([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v22,v21([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v14,v19,v17([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v21,v23([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v18,v20,v22([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v20,v0,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v22,v0,v1([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v5,v8([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v3,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m2.c
new file mode 100644
index 000000000000..c981b3a681e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m2.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e16m2,
+  vuint16m2_t,
+  vuint32m4_t,
+  __riscv_vle16_v_u16m2,
+  __riscv_vle32_v_u32m4,
+  __riscv_vwmaccu_vv_u32m4,
+  __riscv_vse32_v_u32m4,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X8)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e16m2,
+  vuint16m2_t,
+  vuint32m4_t,
+  vuint16m4_t,
+  __riscv_vle16_v_u16m2,
+  __riscv_vle32_v_u32m4,
+  __riscv_vreinterpret_v_u32m4_u16m4,
+  __riscv_vget_v_u16m4_u16m2,
+  __riscv_vwmaccu_vv_u32m4,
+  __riscv_vse32_v_u32m4,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v0,v30([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v0,v28,v26([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v28,v24,v22([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v20,v18([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v20,v16,v14([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v12,v10([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v12,v8,v6([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v4,v2([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v10,v16([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v6,v2([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m4.c
new file mode 100644
index 000000000000..39f42879382b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-m4.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e16m4,
+  vuint16m4_t,
+  vuint32m8_t,
+  __riscv_vle16_v_u16m4,
+  __riscv_vle32_v_u32m8,
+  __riscv_vwmaccu_vv_u32m8,
+  __riscv_vse32_v_u32m8,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X4)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e16m4,
+  vuint16m4_t,
+  vuint32m8_t,
+  vuint16m8_t,
+  __riscv_vle16_v_u16m4,
+  __riscv_vle32_v_u32m8,
+  __riscv_vreinterpret_v_u32m8_u16m8,
+  __riscv_vget_v_u16m8_u16m4,
+  __riscv_vwmaccu_vv_u32m8,
+  __riscv_vse32_v_u32m8,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v0,v4([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v0,v28,v20([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v16,v12([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v8,v12([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v20,v0([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v12,v4([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf2.c
new file mode 100644
index 000000000000..9e5fa5fe3a44
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e16m1,
+  vuint16mf2_t,
+  vuint32m1_t,
+  __riscv_vle16_v_u16mf2,
+  __riscv_vle32_v_u32m1,
+  __riscv_vwmaccu_vv_u32m1,
+  __riscv_vse32_v_u32m1,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+/* The fractional LMUL source has EMUL < 1, thus the widened destination
+   register group must not overlap either source at all.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv} 16 } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),\1,} } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),v[0-9]+,\1([^0-9]|$)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf4.c
new file mode 100644
index 000000000000..52a70b34539e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u16-mf4.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e16m1,
+  vuint16mf4_t,
+  vuint32mf2_t,
+  __riscv_vle16_v_u16mf4,
+  __riscv_vle32_v_u32mf2,
+  __riscv_vwmaccu_vv_u32mf2,
+  __riscv_vse32_v_u32mf2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+/* The fractional LMUL source has EMUL < 1, thus the widened destination
+   register group must not overlap either source at all.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv} 16 } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),\1,} } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),v[0-9]+,\1([^0-9]|$)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m1.c
new file mode 100644
index 000000000000..4e973657c6b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e32m1,
+  vuint32m1_t,
+  vuint64m2_t,
+  __riscv_vle32_v_u32m1,
+  __riscv_vle64_v_u64m2,
+  __riscv_vwmaccu_vv_u64m2,
+  __riscv_vse64_v_u64m2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e32m1,
+  vuint32m1_t,
+  vuint64m2_t,
+  vuint32m2_t,
+  __riscv_vle32_v_u32m1,
+  __riscv_vle64_v_u64m2,
+  __riscv_vreinterpret_v_u64m2_u32m2,
+  __riscv_vget_v_u32m2_u32m1,
+  __riscv_vwmaccu_vv_u64m2,
+  __riscv_vse64_v_u64m2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v12,v30,v29([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v16,v15([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v0,v31([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v14,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v30,v28,v27([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v28,v26,v25([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v6,v20,v19([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v26,v24,v23([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v18,v17([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v10,v1,v15([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v22,v21([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v14,v19,v17([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v21,v23([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v18,v20,v22([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v20,v0,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v22,v0,v1([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v5,v8([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v3,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m2.c
new file mode 100644
index 000000000000..450de0c6fbf3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m2.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e32m2,
+  vuint32m2_t,
+  vuint64m4_t,
+  __riscv_vle32_v_u32m2,
+  __riscv_vle64_v_u64m4,
+  __riscv_vwmaccu_vv_u64m4,
+  __riscv_vse64_v_u64m4,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X8)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e32m2,
+  vuint32m2_t,
+  vuint64m4_t,
+  vuint32m4_t,
+  __riscv_vle32_v_u32m2,
+  __riscv_vle64_v_u64m4,
+  __riscv_vreinterpret_v_u64m4_u32m4,
+  __riscv_vget_v_u32m4_u32m2,
+  __riscv_vwmaccu_vv_u64m4,
+  __riscv_vse64_v_u64m4,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v0,v30([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v0,v28,v26([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v28,v24,v22([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v20,v18([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v20,v16,v14([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v12,v10([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v12,v8,v6([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v4,v2([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v10,v16([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v6,v2([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m4.c
new file mode 100644
index 000000000000..b2a3852f28cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-m4.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e32m4,
+  vuint32m4_t,
+  vuint64m8_t,
+  __riscv_vle32_v_u32m4,
+  __riscv_vle64_v_u64m8,
+  __riscv_vwmaccu_vv_u64m8,
+  __riscv_vse64_v_u64m8,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X4)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e32m4,
+  vuint32m4_t,
+  vuint64m8_t,
+  vuint32m8_t,
+  __riscv_vle32_v_u32m4,
+  __riscv_vle64_v_u64m8,
+  __riscv_vreinterpret_v_u64m8_u32m8,
+  __riscv_vget_v_u32m8_u32m4,
+  __riscv_vwmaccu_vv_u64m8,
+  __riscv_vse64_v_u64m8,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v0,v4([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v0,v28,v20([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v16,v12([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v8,v12([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v20,v0([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v12,v4([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-mf2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-mf2.c
new file mode 100644
index 000000000000..d10c071d49aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u32-mf2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e32m1,
+  vuint32mf2_t,
+  vuint64m1_t,
+  __riscv_vle32_v_u32mf2,
+  __riscv_vle64_v_u64m1,
+  __riscv_vwmaccu_vv_u64m1,
+  __riscv_vse64_v_u64m1,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+/* The fractional LMUL source has EMUL < 1, thus the widened destination
+   register group must not overlap either source at all.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv} 16 } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),\1,} } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),v[0-9]+,\1([^0-9]|$)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m1.c
new file mode 100644
index 000000000000..640d616d6757
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e8m1,
+  vuint8m1_t,
+  vuint16m2_t,
+  __riscv_vle8_v_u8m1,
+  __riscv_vle16_v_u16m2,
+  __riscv_vwmaccu_vv_u16m2,
+  __riscv_vse16_v_u16m2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e8m1,
+  vuint8m1_t,
+  vuint16m2_t,
+  vuint8m2_t,
+  __riscv_vle8_v_u8m1,
+  __riscv_vle16_v_u16m2,
+  __riscv_vreinterpret_v_u16m2_u8m2,
+  __riscv_vget_v_u8m2_u8m1,
+  __riscv_vwmaccu_vv_u16m2,
+  __riscv_vse16_v_u16m2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v12,v30,v29([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v16,v15([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v0,v31([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v14,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v30,v28,v27([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v28,v26,v25([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v6,v20,v19([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v26,v24,v23([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v18,v17([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v10,v1,v15([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v22,v21([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v14,v19,v17([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v21,v23([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v18,v20,v22([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v20,v0,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v22,v0,v1([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v5,v8([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v2,v3,v1([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m2.c
new file mode 100644
index 000000000000..f26a889dc219
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m2.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e8m2,
+  vuint8m2_t,
+  vuint16m4_t,
+  __riscv_vle8_v_u8m2,
+  __riscv_vle16_v_u16m4,
+  __riscv_vwmaccu_vv_u16m4,
+  __riscv_vse16_v_u16m4,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X8)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e8m2,
+  vuint8m2_t,
+  vuint16m4_t,
+  vuint8m4_t,
+  __riscv_vle8_v_u8m2,
+  __riscv_vle16_v_u16m4,
+  __riscv_vreinterpret_v_u16m4_u8m4,
+  __riscv_vget_v_u8m4_u8m2,
+  __riscv_vwmaccu_vv_u16m4,
+  __riscv_vse16_v_u16m4,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v0,v30([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v0,v28,v26([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v28,v24,v22([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v20,v18([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v20,v16,v14([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v12,v10([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v12,v8,v6([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v4,v2([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v10,v16([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v4,v6,v2([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m4.c
new file mode 100644
index 000000000000..ca257a860416
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-m4.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e8m4,
+  vuint8m4_t,
+  vuint16m8_t,
+  __riscv_vle8_v_u8m4,
+  __riscv_vle16_v_u16m8,
+  __riscv_vwmaccu_vv_u16m8,
+  __riscv_vse16_v_u16m8,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X4)
+
+DEF_GROUP_OVERLAP_TERNARY_1(
+  __riscv_vsetvlmax_e8m4,
+  vuint8m4_t,
+  vuint16m8_t,
+  vuint8m8_t,
+  __riscv_vle8_v_u8m4,
+  __riscv_vle16_v_u16m8,
+  __riscv_vreinterpret_v_u16m8_u8m8,
+  __riscv_vget_v_u8m8_u8m4,
+  __riscv_vwmaccu_vv_u16m8,
+  __riscv_vse16_v_u16m8,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_OVERLAP_X2)
+
+/* ternary_0: the accumulator occupies the whole destination register group and
+   is live when the narrowed sources are read, so no source can be allocated
+   inside the destination register group.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v0,v4([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v0,v28,v20([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v24,v16,v12([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v8,v12([^0-9]|$)} 1 } } */
+
+/* ternary_1: each narrowed source is the highest-numbered half of its own
+   accumulator, thus it overlaps the highest-numbered part of the destination
+   register group.  Without the group overlap the sources would have to be
+   copied out to a disjoint register group first.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v16,v20,v0([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv\s+v8,v12,v4([^0-9]|$)} 1 } } */
+/* { dg-final { scan-assembler-not {vmv[0-9]+r\.v} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf2.c
new file mode 100644
index 000000000000..49e1731e0c5f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e8m1,
+  vuint8mf2_t,
+  vuint16m1_t,
+  __riscv_vle8_v_u8mf2,
+  __riscv_vle16_v_u16m1,
+  __riscv_vwmaccu_vv_u16m1,
+  __riscv_vse16_v_u16m1,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+/* The fractional LMUL source has EMUL < 1, thus the widened destination
+   register group must not overlap either source at all.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv} 16 } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),\1,} } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),v[0-9]+,\1([^0-9]|$)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf4.c
new file mode 100644
index 000000000000..00ecea9af4db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf4.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e8m1,
+  vuint8mf4_t,
+  vuint16mf2_t,
+  __riscv_vle8_v_u8mf4,
+  __riscv_vle16_v_u16mf2,
+  __riscv_vwmaccu_vv_u16mf2,
+  __riscv_vse16_v_u16mf2,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+/* The fractional LMUL source has EMUL < 1, thus the widened destination
+   register group must not overlap either source at all.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv} 16 } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),\1,} } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),v[0-9]+,\1([^0-9]|$)} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf8.c
new file mode 100644
index 000000000000..9a8f4c8a5a68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/group_overlap/vwmaccu_vv-u8-mf8.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "group_overlap.h"
+
+DEF_GROUP_OVERLAP_TERNARY_0(
+  __riscv_vsetvlmax_e8m1,
+  vuint8mf8_t,
+  vuint16mf4_t,
+  __riscv_vle8_v_u8mf8,
+  __riscv_vle16_v_u16mf4,
+  __riscv_vwmaccu_vv_u16mf4,
+  __riscv_vse16_v_u16mf4,
+  vwmaccu_vv,
+  LOOP_DUAL_WIDEN_TERNARY_BODY_X16)
+
+/* The fractional LMUL source has EMUL < 1, thus the widened destination
+   register group must not overlap either source at all.  */
+/* { dg-final { scan-assembler-times {vwmaccu\.vv} 16 } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),\1,} } } */
+/* { dg-final { scan-assembler-not {vwmaccu\.vv\s+(v[0-9]+),v[0-9]+,\1([^0-9]|$)} } } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.