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. */