https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128371
Bug ID: 128371
Summary: [RISC-V] Zicfilp: lp-label clear for -msave-restore
millicode is emitted after the function's last insn
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
Target Milestone: ---
Target: riscv*-*-*
Reproducer
----------
$ cat trigger.c
extern int leaf (int);
extern void use (int);
int
foo (int n)
{
int a = n + 1, b = n + 2, c = n + 3, d = n + 4;
a += leaf (a);
b += leaf (b);
c += leaf (c);
d += leaf (d);
use (a + b + c + d);
return leaf (a + b + c + d + n);
}
Compile flag: riscv64-linux-gnu-gcc -O2 -march=rv64gc_zicfilp -mabi=lp64d
-msave-restore -fcf-protection=branch -S trigger.c
foo:
lpad 0
.align 2
call t0,__riscv_save_5 # no t2 set before the millicode call
lpad 0
...
call leaf
tail __riscv_restore_5 # no t2 set before the millicode call
li t2,0 # emitted for gpr_save, unreachable
li t2,0 # emitted for gpr_restore, unreachable
.LFE0:
Root cause
----------
rest_of_insert_landing_pad (gcc/config/riscv/riscv-zicfilp.cc:115-124)
handles CODE_FOR_gpr_save / CODE_FOR_gpr_restore with
emit_move_insn (RISCV_CALL_ADDRESS_LPAD (Pmode), const0_rtx);
without an insertion point. emit_move_insn -> emit_insn -> add_insn links
after get_last_insn (), so both moves land after the last insn of the
function instead of before the millicode call. The neighbouring lpad
insns correctly use emit_insn_before/emit_insn_after.
Suggested Fix
-------------
Use emit_insn_before (gen_move_insn (RISCV_CALL_ADDRESS_LPAD (Pmode),
const0_rtx), insn) for both the gpr_save and the gpr_restore case.