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.

Reply via email to