https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85876
--- Comment #1 from Andrey Belevantsev <abel at gcc dot gnu.org> --- This is caused by the overeager fix of PR 48235. We're unwinding the first_insn variable (the border to which we step backwards in code motion) too far so it gets beyond the original fence, which happens to be mid-block instead of bb head. Fixed as below. Alexander, do you remember anything else about that PR (e.g. I think there was a code to unwind the fence back to account for the unscheduled instructions, but this is not it). diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 315f2c0c0ab..6116e43f998 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -6437,7 +6437,7 @@ code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path, { expr_t expr = NULL; basic_block bb = BLOCK_FOR_INSN (insn); - insn_t first_insn, bb_tail, before_first; + insn_t first_insn, original_insn, bb_tail, before_first; bool removed_last_insn = false; if (sched_verbose >= 6) @@ -6521,7 +6521,7 @@ code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path, /* It is enough to place only heads and tails of visited basic blocks into the PATH. */ ilist_add (&path, insn); - first_insn = insn; + first_insn = original_insn = insn; bb_tail = sel_bb_end (bb); /* Descend the basic block in search of the original expr; this part @@ -6628,6 +6628,8 @@ code_motion_path_driver (insn_t insn, av_set_t orig_ops, ilist_t path, { insn = sel_bb_end (bb); first_insn = sel_bb_head (bb); + if (first_insn != original_insn) + first_insn = original_insn; } /* Remove bb tail from path. */