https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87273

--- Comment #5 from Andrey Belevantsev <abel at gcc dot gnu.org> ---
In this PR we're pipelining a loop with a conditional that has lots of code on
the left arm and just a few blocks on the right arm.  In this situation it is
natural for the right scheduling fence to end up fast below the conditional (on
its postdominating block), and for the left fences to get there much later.

When this happens, we merge the fences, and in that code there is an assert
that basically says (as far as I remember, this is the code that goes back to
the original sel-sched commit) that, if we're merging two fences and one came
from a fallthrough block, then another is supposed to come from the second
block.  But it is not the case here, because the left fence (the later one) has
already scheduled an insn from the code that was processed by the right fence
(the earlier one), and this insn therefore has moved from block 7 of the
earlier fence to block 6 of the later one.  So both fences are saying that
previously they have scheduled some code from the same block 6, and that fires
the assert.

As I said, the situation is completely normal and I don't see the point in
keeping the assert anymore.  So just removing it fixes the issue as with the
below patch.

diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index e8e508ef692..a6583017c9d 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -703,11 +703,6 @@ merge_fences (fence_t f, insn_t insn,
       else
         if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn))
           {
-            /* Would be weird if same insn is successor of several fallthrough
-               edges.  */
-            gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb
-                        != BLOCK_FOR_INSN (last_scheduled_insn_old));
-
             state_free (FENCE_STATE (f));
             FENCE_STATE (f) = state;

Reply via email to