https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98439
Uroš Bizjak <ubizjak at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|target |rtl-optimization Last reconfirmed| |2020-12-27 Ever confirmed|0 |1 Status|UNCONFIRMED |NEW --- Comment #1 from Uroš Bizjak <ubizjak at gmail dot com> --- Confirmed as rtl-optimization problem. Before sched2 pass, we have: (insn 26 7 8 2 (set (reg:SI 0 ax [85]) (reg:SI 20 xmm0 [89])) "pr98439.c":9:10 75 {*movsi_internal} (insn 8 26 39 2 (set (mem:SI (pre_modify:DI (reg/f:DI 7 sp) (plus:DI (reg/f:DI 7 sp) (const_int -8 [0xfffffffffffffff8]))) [0 S4 A32]) (reg:SI 0 ax [85])) "pr98439.c":9:10 53 {*pushsi2_rex64} which is transformed by sched2 pass to: (insn:TI 46 44 26 2 (set (mem:SI (pre_modify:DI (reg/f:DI 7 sp) (plus:DI (reg/f:DI 7 sp) (const_int -8 [0xfffffffffffffff8]))) [0 S4 A32]) (reg:SI 20 xmm0 [89])) 53 {*pushsi2_rex64} (insn 26 46 15 2 (set (reg:SI 0 ax [85]) (reg:SI 20 xmm0 [89])) "pr98439.c":9:10 75 {*movsi_internal} (insn 46) is defined in i386.md as: (define_insn "*pushsi2_rex64" [(set (match_operand:SI 0 "push_operand" "=X,X") (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))] "TARGET_64BIT" "@ push{q}\t%q1 #" [(set_attr "type" "push,multi") (set_attr "mode" "DI")]) xmm0 is allowed by *v constraint, but the insn has to be split. Since sched2 pass comes after split3 pass, we hit the assert in final_scan_insn_1: /* If the template is the string "#", it means that this insn must be split. */ if (templ[0] == '#' && templ[1] == '\0') { rtx_insn *new_rtx = try_split (body, insn, 0); /* If we didn't split the insn, go away. */ if (new_rtx == insn && PATTERN (new_rtx) == body) fatal_insn ("could not split insn", insn); /* If we have a length attribute, this instruction should have been split in shorten_branches, to ensure that we would have valid length info for the splitees. */ --> gcc_assert (!HAVE_ATTR_length); return new_rtx; } As the comment says, this insn should have been split in shorten_branches, but: /* The placement of the splitting that we do for shorten_branches depends on whether regstack is used by the target or not. */ #if HAVE_ATTR_length && !defined (STACK_REGS) return true; #else return false; #endif and nothing splits insns after sched2, because: bool pass_split_before_regstack::gate (function *) { #if HAVE_ATTR_length && defined (STACK_REGS) /* If flow2 creates new instructions which need splitting and scheduling after reload is not done, they might not be split until final which doesn't allow splitting if HAVE_ATTR_length. */ return !enable_split_before_sched2 (); #else return false; #endif } and finally: static bool enable_split_before_sched2 (void) { #ifdef INSN_SCHEDULING return optimize > 0 && flag_schedule_insns_after_reload; #else return false; #endif }