https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70030
Bug ID: 70030 Summary: [LRA]ICE when reload insn with output scratch operand Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: renlin at gcc dot gnu.org Target Milestone: --- The ICE is triggered when building linux toolchain with local change to gcc aarch64 backend. vfprintf.c: In function ‘_IO_vfwprintf’: vfprintf.c:1689:1: internal compiler error: in lra_set_insn_recog_data, at lra.c:964 } ^ 0x952998 lra_set_insn_recog_data(rtx_insn*) src/gcc/gcc/lra.c:962 0x9537b6 lra_get_insn_recog_data src/gcc/gcc/lra-int.h:486 0x9537b6 lra_update_insn_regno_info src/gcc/gcc/lra.c:1584 0x9537b6 lra_update_insn_regno_info src/gcc/gcc/lra.c:1574 0x953a82 lra_push_insn_1 src/gcc/gcc/lra.c:1649 0x953a82 lra_push_insn(rtx_insn*) src/gcc/gcc/lra.c:1657 0x953cb7 push_insns gcc/gcc/lra.c:1700 0x954191 lra_process_new_insns(rtx_insn*, rtx_insn*, rtx_insn*, char const*) gcc/gcc/lra.c:1754 0x9670e5 curr_insn_transform src/gcc/gcc/lra-constraints.c:3962 0x968866 lra_constraints(bool) src/gcc/gcc/lra-constraints.c:4450 0x954cb2 lra(_IO_FILE*) src/gcc/gcc/lra.c:2277 0x90cfa9 do_reload src/gcc/gcc/ira.c:5395 0x90cfa9 execute src/gcc/gcc/ira.c:5566 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. The situation is like this, To make insn_1 strict, lra generates a new insn_1_reload insn. In insn_1_reload, there is a scratch operand with this form clobber (match_scratch:MODE x "=r") It's written in this way to reserve a pseudo register which will be used as temporary within the pattern. When lra tries to reload insn_1_reload in later iteration, a new pseudo register (let say RXX) is created to replace this scratch operand in-place. Additionally, a new insn will be generated and inserted after insn_1_reload to finish the reload. It's in this form: (set scratch, RXX) And this instruction is illegal. no target implements this kind of pattern. LRA will ICE because of this. (1) if (get_reload_reg (type, mode, old, goal_alt[i], loc != curr_id->operand_loc[i], "", &new_reg) && type != OP_OUT) { push_to_sequence (before); lra_emit_move (new_reg, old); before = get_insns (); end_sequence (); } (2) *loc = new_reg; if (type != OP_IN && find_reg_note (curr_insn, REG_UNUSED, old) == NULL_RTX) { start_sequence (); (3) lra_emit_move (type == OP_INOUT ? copy_rtx (old) : old, new_reg); emit_insn (after); after = get_insns (); end_sequence (); *loc = new_reg; } (1) a reload pseudo register is generated: RXX (2) replace original operand in-place: (clobber RXX) (3) insert insn to set output operand: (set scratch, RXX)