[gcc r17-3493] RISC-V: Fix ICE passing an empty aggregate under the VLS calling convention

Kito Cheng via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:9c5e44d17b55c698d3e48b7b6ad3a15d6cae2f9b

commit r17-3493-g9c5e44d17b55c698d3e48b7b6ad3a15d6cae2f9b
Author: Kito Cheng <[email protected]>
Date:   Mon Aug 17 14:55:14 2026 +0800

    RISC-V: Fix ICE passing an empty aggregate under the VLS calling convention
    
    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.

Diff:
---
 gcc/config/riscv/riscv.cc                          |  2 +-
 .../g++.target/riscv/vls-cc-empty-aggregate.C      | 30 ++++++++++++++++++++++
 .../gcc.target/riscv/rvv/vls-cc/empty-aggregate.c  | 30 ++++++++++++++++++++++
 3 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index a2a51c019ec1..d61461e256e2 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -7206,7 +7206,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 000000000000..43e13c39598c
--- /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 000000000000..bd51ca8b6508
--- /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 ();
+}
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.