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

Reply via email to