https://gcc.gnu.org/g:868b14a1abc1d96bb003c355ca81c5acfa72f337
commit r17-1444-g868b14a1abc1d96bb003c355ca81c5acfa72f337 Author: Monk Chiang <[email protected]> Date: Tue Jun 9 06:47:50 2026 -0600 [PATCH v2] RISC-V: Optimize trampoline code generation for Zicfilp The trampoline code generation for Zicfilp (CFI landing pads) uses three registers and includes a redundant LUI instruction. Before this patch, the trampoline code was: lpad 0 auipc t3, 0 l[wd] t0, (target_function_offset - 4)(t3) l[wd] t3, (static_chain_offset - 4)(t3) lui t2, 0 jr t0 This uses three registers (t0, t2, t3) and has a redundant "lui t2, 0" instruction that is never used. After this patch, the trampoline code is: lpad 0 auipc t3, 0 l[wd] t2, (target_function_offset - 4)(t3) l[wd] t3, (static_chain_offset - 4)(t3) jr t2 nop The optimization removes the redundant LUI instruction, uses only two registers (t2, t3), and adds a nop for proper 8-byte alignment to avoid -Wpadded warnings. Changes in v2: - Fix zicfilp-trampoline test for Linux targets. - Fix line length exceeding 80 characters. gcc/ * config/riscv/riscv.cc (riscv_trampoline_init): Remove redundant LUI instruction. gcc/testsuite/ * gcc.target/riscv/zicfilp-trampoline.c: New test. Diff: --- gcc/config/riscv/riscv.cc | 19 +++++++++---------- gcc/testsuite/gcc.target/riscv/zicfilp-trampoline.c | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 623aaa83b0ec..e70df9530d94 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -12504,28 +12504,27 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value) } else { - /* lpad 1 + /* lpad 0 auipc t3, 0 - l[wd] t0, (target_function_offset - 4)(t3) + l[wd] t2, (target_function_offset - 4)(t3) l[wd] t3, (static_chain_offset - 4)(t3) - lui t2, 1 - jr t0 + jr t2 + nop */ trampoline_cfi[0] = OPCODE_AUIPC | (0 << SHIFT_RD) | (lp_value << IMM_BITS); trampoline_cfi[1] = OPCODE_AUIPC | (STATIC_CHAIN_REGNUM << SHIFT_RD); trampoline_cfi[2] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) - | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RD) + | (RISCV_CALL_ADDRESS_LPAD_REGNUM << SHIFT_RD) | (STATIC_CHAIN_REGNUM << SHIFT_RS1) | ((target_function_offset - 4) << SHIFT_IMM); trampoline_cfi[3] = (Pmode == DImode ? OPCODE_LD : OPCODE_LW) | (STATIC_CHAIN_REGNUM << SHIFT_RD) | (STATIC_CHAIN_REGNUM << SHIFT_RS1) | ((static_chain_offset - 4) << SHIFT_IMM); - trampoline_cfi[4] = OPCODE_LUI - | (RISCV_CALL_ADDRESS_LPAD_REGNUM << SHIFT_RD) - | (lp_value << IMM_BITS); - trampoline_cfi[5] = OPCODE_JALR | (RISCV_PROLOGUE_TEMP_REGNUM << SHIFT_RS1); - + trampoline_cfi[4] = OPCODE_JALR + | (RISCV_CALL_ADDRESS_LPAD_REGNUM << SHIFT_RS1); + trampoline_cfi[5] = OPCODE_ADDI | (0 << SHIFT_RD) + | (0 << SHIFT_RS1) | (0 << SHIFT_IMM); /* Copy the trampoline code. */ for (i = 0; i < ARRAY_SIZE (trampoline_cfi); i++) { diff --git a/gcc/testsuite/gcc.target/riscv/zicfilp-trampoline.c b/gcc/testsuite/gcc.target/riscv/zicfilp-trampoline.c new file mode 100644 index 000000000000..575708365e69 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/zicfilp-trampoline.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { riscv64*-*-* } } } */ +/* { dg-require-effective-target trampolines } */ +/* { dg-options "-Wpadded -march=rv64gc_zicfilp -mabi=lp64d -fcf-protection=branch -O2" } */ +/* { dg-final { scan-assembler "lpad\\s+0" } } */ + +extern int baz(int (*) (int)); +int foo(void) +{ + int k = 3; + int bar(int x) { + return x + k; + } + return baz(bar); +}
