[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 (); +}