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