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" } } */
