[gcc r17-2809] RISC-V: Fix sibcall address legalization in MI thunks [PR126449]
Ma Jin via Gcc-cvs <[email protected]> Thu, 30 Jul 2026 07:46:00 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:4e75c08f16fd97c1459320738b59068f8d003500 commit r17-2809-g4e75c08f16fd97c1459320738b59068f8d003500 Author: Jin Ma <[email protected]> Date: Tue Jul 28 19:58:16 2026 +0800 RISC-V: Fix sibcall address legalization in MI thunks [PR126449] MI thunks generate RTL as if reload were complete and emit it directly without running register allocation. Creating a pseudo while materializing an invalid sibcall address therefore triggers the gen_reg_rtx assertion. Use STATIC_CHAIN_REGNUM for this post-reload thunk path. It is available as a temporary in MI thunks and belongs to SIBCALL_REGS. Keep using a pseudo for sibcalls expanded before register allocation. PR target/126449 gcc/ChangeLog: * config/riscv/riscv.cc (riscv_legitimize_call_address): Use STATIC_CHAIN_REGNUM when a sibcall address is materialized in post-reload thunk code. gcc/testsuite/ChangeLog: * g++.target/riscv/pr126449.C: New test. Reported-by: Michal Jireš <[email protected]> Signed-off-by: Jin Ma <[email protected]> Diff: --- gcc/config/riscv/riscv.cc | 17 ++++++++++++++--- gcc/testsuite/g++.target/riscv/pr126449.C | 23 +++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index a401c0c7c93e..d813f03b549f 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -8110,9 +8110,20 @@ riscv_legitimize_call_address (rtx addr, bool sibcall_p) { if (!call_insn_operand (addr, VOIDmode)) { - rtx reg = sibcall_p - ? gen_reg_rtx (Pmode) - : RISCV_CALL_ADDRESS_TEMP (Pmode); + rtx reg; + if (sibcall_p && can_create_pseudo_p ()) + reg = gen_reg_rtx (Pmode); + else if (sibcall_p) + { + /* MI thunks are expanded as post-reload code and cannot create + pseudos. STATIC_CHAIN_REGNUM is available as a temporary there + and is suitable for an indirect sibling call. */ + gcc_assert (riscv_in_thunk_func + && SIBCALL_REG_P (STATIC_CHAIN_REGNUM)); + reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM); + } + else + reg = RISCV_CALL_ADDRESS_TEMP (Pmode); riscv_emit_move (reg, addr); if (is_zicfilp_p ()) diff --git a/gcc/testsuite/g++.target/riscv/pr126449.C b/gcc/testsuite/g++.target/riscv/pr126449.C new file mode 100644 index 000000000000..f5f4c90b3ebf --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/pr126449.C @@ -0,0 +1,23 @@ +/* PR target/126449 */ +/* { dg-do compile { target { rv64 } } } */ +/* { dg-options "-mcmodel=large -fno-pie" } */ + +struct AddIn +{ + virtual ~AddIn (); +}; + +struct Base +{ + virtual ~Base (); +}; + +struct Deriv : Base, AddIn +{ +}; + +int +main () +{ + Deriv deriv; +}