https://gcc.gnu.org/g:b460a877061a71daeed6f7fca01b8274d9fdd9da

commit r17-2469-gb460a877061a71daeed6f7fca01b8274d9fdd9da
Author: Jin Ma <[email protected]>
Date:   Thu Jul 16 15:56:08 2026 +0800

    RISC-V: Use a pseudo for sibcall addresses
    
    SIBCALL_REGS excludes t1, so the "j" constraint makes LRA reload a
    sibcall address materialized in t1.  Sibcalls are therefore correct
    without this change.
    
    Use a pseudo for sibcall address materialization so allocation can
    select SIBCALL_REGS directly and avoid the reload.  Keep t1 for normal
    calls.  This is an optimization, not a bug fix.
    
    gcc/ChangeLog:
    
            * config/riscv/riscv-protos.h
            (riscv_legitimize_call_address): Add a sibcall parameter.
            * config/riscv/riscv.cc
            (riscv_legitimize_call_address): Use a pseudo for sibcalls.
            * config/riscv/riscv.md (sibcall): Pass true for sibcalls.
            (sibcall_value): Likewise.
            (call): Pass false for ordinary calls.
            (call_value): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/sibcall-materialize-pseudo.c: New test.

Diff:
---
 gcc/config/riscv/riscv-protos.h                      |  2 +-
 gcc/config/riscv/riscv.cc                            |  8 +++++---
 gcc/config/riscv/riscv.md                            |  8 ++++----
 .../gcc.target/riscv/sibcall-materialize-pseudo.c    | 20 ++++++++++++++++++++
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 3da840fab470..3843110ab6c2 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -155,7 +155,7 @@ extern rtx riscv_emit_unary (enum rtx_code code, rtx dest, 
rtx x);
 extern rtx riscv_emit_binary (enum rtx_code code, rtx dest, rtx x, rtx y);
 #endif
 extern bool riscv_expand_conditional_move (rtx, rtx, rtx, rtx);
-extern rtx riscv_legitimize_call_address (rtx);
+extern rtx riscv_legitimize_call_address (rtx, bool);
 extern bool riscv_call_needs_lpad_p (rtx);
 extern bool riscv_expand_zilsd_misaligned_move (rtx, rtx);
 extern bool riscv_zilsd_valid_mem_p (rtx, machine_mode);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 596145ca19c1..57e798556d04 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -8103,14 +8103,16 @@ riscv_va_start (tree valist, rtx nextarg)
   std_expand_builtin_va_start (valist, nextarg);
 }
 
-/* Make ADDR suitable for use as a call or sibcall target.  */
+/* Make ADDR a valid call target.  */
 
 rtx
-riscv_legitimize_call_address (rtx addr)
+riscv_legitimize_call_address (rtx addr, bool sibcall_p)
 {
   if (!call_insn_operand (addr, VOIDmode))
     {
-      rtx reg = RISCV_CALL_ADDRESS_TEMP (Pmode);
+      rtx reg = sibcall_p
+               ? gen_reg_rtx (Pmode)
+               : RISCV_CALL_ADDRESS_TEMP (Pmode);
       riscv_emit_move (reg, addr);
 
       if (is_zicfilp_p ())
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index c64e4ff3c77b..5e7117f77473 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -4153,7 +4153,7 @@
              (use (match_operand 2 ""))])]
   ""
 {
-  rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
+  rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0), true);
   emit_call_insn (gen_sibcall_internal (target, operands[1]));
   DONE;
 })
@@ -4175,7 +4175,7 @@
              (use (match_operand 3 ""))])]
   ""
 {
-  rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
+  rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0), true);
   emit_call_insn (gen_sibcall_value_internal (operands[0], target,
                                              operands[2]));
   DONE;
@@ -4199,7 +4199,7 @@
   ""
 {
   rtx addr = XEXP (operands[0], 0);
-  rtx target = riscv_legitimize_call_address (addr);
+  rtx target = riscv_legitimize_call_address (addr, false);
   if (riscv_call_needs_lpad_p (addr))
     emit_call_insn (gen_call_internal_cfi (target, operands[1]));
   else
@@ -4257,7 +4257,7 @@
   ""
 {
   rtx addr = XEXP (operands[1], 0);
-  rtx target = riscv_legitimize_call_address (addr);
+  rtx target = riscv_legitimize_call_address (addr, false);
   if (riscv_call_needs_lpad_p (addr))
     emit_call_insn (gen_call_value_internal_cfi (operands[0], target,
                                                 operands[2]));
diff --git a/gcc/testsuite/gcc.target/riscv/sibcall-materialize-pseudo.c 
b/gcc/testsuite/gcc.target/riscv/sibcall-materialize-pseudo.c
new file mode 100644
index 000000000000..db0149d69d1a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/sibcall-materialize-pseudo.c
@@ -0,0 +1,20 @@
+/* { dg-do compile { target { rv64 } } } */
+/* { dg-options "-O2 -fPIC -fdump-rtl-expand" } */
+
+extern int callee_value (int) __attribute__ ((weak));
+extern void callee_void (int) __attribute__ ((weak));
+
+int
+caller_value (int x)
+{
+  return callee_value (x);
+}
+
+void
+caller_void (int x)
+{
+  callee_void (x);
+}
+
+/* { dg-final { scan-rtl-dump-times {call_insn/j} 2 "expand" } } */
+/* { dg-final { scan-rtl-dump-not {reg:DI 6 t1} "expand" } } */

Reply via email to