There is the following mistake in logic behind the code.
We want to schedule the branch instructions only as a last instruction
in a row. But when branch was scheduled and we add other instructions
into partial schedule, we sometimes allow them to be in same row after
the branch.
The issue happens later when we try to reschedule branch into another
row, algorithm there works like this:
(1) Remove branch from the row where it is (say, “previous row”)
(2) Try insert into the needed row
(3) If success – OK, continue scheduling other instructions
(4) But when inserting (2) was not done – insert it back into “previous
row” and this insertion must be certainly successful, which is checked
by assertion.
But when on step (1) branch in not last in a row there is no guarantee,
that on step (4) we could insert it back, because there we will try only
last-in-a-row position for it.
This patch solves this totally preventing other instructions to be
scheduled after branch in the same row.
I’ve described patch testing in cover letter. Ok for trunk?
gcc/ChangeLog:
2019-04-09 Roman Zhuykov <zhr...@ispras.ru>
PR rtl-optimization/84032
* modulo-sched.c (ps_insn_find_column): Change condition so that
branch will always be the last insn in a row inside partial schedule.
gcc/testsuite/ChangeLog:
2019-04-09 Roman Zhuykov <zhr...@ispras.ru>
PR rtl-optimization/84032
* gcc.dg/pr84032.c: New test.
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -2996,9 +2996,7 @@ ps_insn_find_column (partial_schedule_ptr ps,
ps_insn_ptr ps_i,
last_must_precede = next_ps_i;
}
/* The closing branch must be the last in the row. */
- if (must_precede
- && bitmap_bit_p (must_precede, next_ps_i->id)
- && JUMP_P (ps_rtl_insn (ps, next_ps_i->id)))
+ if (JUMP_P (ps_rtl_insn (ps, next_ps_i->id)))
return false;
last_in_row = next_ps_i;
diff --git a/gcc/testsuite/gcc.dg/pr84032.c
b/gcc/testsuite/gcc.dg/pr84032.c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr84032.c
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/84032 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fmodulo-sched" } */
+/* { dg-additional-options "-mcpu=power6" { target { powerpc-*-* } } }
*/
+
+void
+yr (int cm)
+{
+ int ka = cm;
+
+ for (;;)
+ {
+ short int m0;
+
+ for (m0 = 0; m0 < 6; ++m0)
+ {
+ ka &= 1;
+ cm *= 2;
+ }
+
+ ka = (ka == 0) ? cm : 0;
+ }
+}