riscv_flatten_aggregate_argument returns 0 for an aggregate with no field,
but riscv_pass_aggregate_in_vr only rejected -1 and then read fields[0],
which was never written:

    struct empty { };
    __attribute__((riscv_vls_cc(1024))) void fr (struct empty x) { }

    internal compiler error: tree check: expected class 'type', have
    'exceptional' (error_mark) in riscv_pass_aggregate_in_vr

An aggregate with no field has nothing to put in a vector register, so
return NULL_RTX and let the generic path handle it, the same as any other
aggregate that does not fit the vector calling convention.

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_pass_aggregate_in_vr): Return
        NULL_RTX for an aggregate with no field.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/vls-cc/empty-aggregate.c: New test.
        * g++.target/riscv/vls-cc-empty-aggregate.C: New test.
---
 gcc/config/riscv/riscv.cc                     |  2 +-
 .../g++.target/riscv/vls-cc-empty-aggregate.C | 30 +++++++++++++++++++
 .../riscv/rvv/vls-cc/empty-aggregate.c        | 30 +++++++++++++++++++
 3 files changed, 61 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.target/riscv/vls-cc-empty-aggregate.C
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/vls-cc/empty-aggregate.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index c8139ea9073..d4dfb471fd4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7426,7 +7426,7 @@ riscv_pass_aggregate_in_vr (struct riscv_arg_info *info,
   int n = riscv_flatten_aggregate_argument (type, fields, true, true,
                                            /* vls_p */ true, abi_vlen);
 
-  if (n == -1)
+  if (n <= 0)
     return NULL_RTX;
 
   /* Check all field has same size.  */
diff --git a/gcc/testsuite/g++.target/riscv/vls-cc-empty-aggregate.C 
b/gcc/testsuite/g++.target/riscv/vls-cc-empty-aggregate.C
new file mode 100644
index 00000000000..43e13c39598
--- /dev/null
+++ b/gcc/testsuite/g++.target/riscv/vls-cc-empty-aggregate.C
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d" } */
+
+/* An aggregate with no field has nothing to pass in a vector register.  It
+   used to run an empty field list into riscv_pass_aggregate_in_vr.  */
+
+struct empty { };
+struct derived : empty { };
+
+__attribute__((riscv_vls_cc(1024))) void arg (empty);
+__attribute__((riscv_vls_cc(1024))) void arg_derived (derived);
+__attribute__((riscv_vls_cc(1024))) empty ret ();
+
+__attribute__((riscv_vls_cc(1024))) void
+def_arg (empty x)
+{
+  arg (x);
+}
+
+__attribute__((riscv_vls_cc(1024))) void
+def_arg_derived (derived x)
+{
+  arg_derived (x);
+}
+
+__attribute__((riscv_vls_cc(1024))) void
+call_ret ()
+{
+  ret ();
+}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vls-cc/empty-aggregate.c 
b/gcc/testsuite/gcc.target/riscv/rvv/vls-cc/empty-aggregate.c
new file mode 100644
index 00000000000..bd51ca8b650
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vls-cc/empty-aggregate.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl512b -mabi=lp64d -Wno-psabi" } */
+
+/* An aggregate with no field has nothing to pass in a vector register.  It
+   used to run an empty field list into riscv_pass_aggregate_in_vr.  */
+
+struct empty { };
+struct empty_array { struct empty a[0]; };
+
+__attribute__((riscv_vls_cc(1024))) void arg (struct empty);
+__attribute__((riscv_vls_cc(1024))) void arg_array (struct empty_array);
+__attribute__((riscv_vls_cc(1024))) struct empty ret (void);
+
+__attribute__((riscv_vls_cc(1024))) void
+def_arg (struct empty x)
+{
+  arg (x);
+}
+
+__attribute__((riscv_vls_cc(1024))) void
+def_arg_array (struct empty_array x)
+{
+  arg_array (x);
+}
+
+__attribute__((riscv_vls_cc(1024))) void
+call_ret (void)
+{
+  ret ();
+}
-- 
2.54.0

Reply via email to