passes: Enable split4 with selective scheduling 2 [PR98439]
authorJakub Jelinek <jakub@redhat.com>
Sat, 13 Feb 2021 15:08:29 +0000 (16:08 +0100)
committerJakub Jelinek <jakub@redhat.com>
Sat, 13 Feb 2021 15:08:29 +0000 (16:08 +0100)
As mentioned in the PR, we have 5 split passes (+ splitting during final).
split1 is before RA and is unconditional,
split2 is after RA and is gated on optimize > 0,
split3 is before sched2 and is gated on
  defined(INSN_SCHEDULING) && optimize > 0 && flag_schedule_insns_after_reload
split4 is before regstack and is gated on
  HAVE_ATTR_length && defined (STACK_REGS) && !gate (split3)
split5 is before shorten_branches and is gated on
  HAVE_ATTR_length && !defined (STACK_REGS)
and the splitting during final works only when !HAVE_ATTR_length.
STACK_REGS is a macro enabled only on i386/x86_64.

The problem with the following testcase is that split3 before sched2
is the last splitting pass for the target/command line options set,
but selective scheduling unlike normal scheduling can create new
instructions that need to be split, which means we ICE during final as
there are insns that require splitting but nothing split them.

This patch fixes it by doing split4 also when -fselective-scheduling2
is enabled on x86 and split3 has been run.  As that option isn't on
by default, it should slow down compilation only for those that enable
that option.

2021-02-13  Jakub Jelinek  <jakub@redhat.com>

PR rtl-optimization/98439
* recog.c (pass_split_before_regstack::gate): Enable even when
pass_split_before_sched2 is enabled if -fselective-scheduling2 is
on.

* gcc.target/i386/pr98439.c: New test.

gcc/recog.c
gcc/testsuite/gcc.target/i386/pr98439.c [new file with mode: 0644]

index 1f43237edad9fda645e3c5128535043e24d97be1..abbc49f3f9b8da3facb4bec835a209e2c1224d70 100644 (file)
@@ -4532,8 +4532,13 @@ pass_split_before_regstack::gate (function *)
   /* If flow2 creates new instructions which need splitting
      and scheduling after reload is not done, they might not be
      split until final which doesn't allow splitting
-     if HAVE_ATTR_length.  */
+     if HAVE_ATTR_length.  Selective scheduling can result in
+     further instructions that need splitting.  */
+#ifdef INSN_SCHEDULING
+  return !enable_split_before_sched2 () || flag_selective_scheduling2;
+#else
   return !enable_split_before_sched2 ();
+#endif
 #else
   return false;
 #endif
diff --git a/gcc/testsuite/gcc.target/i386/pr98439.c b/gcc/testsuite/gcc.target/i386/pr98439.c
new file mode 100644 (file)
index 0000000..02fc40a
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR rtl-optimization/98439 */
+/* { dg-do compile } */
+/* { dg-options "-march=nehalem -O2 -fselective-scheduling2 -fno-cprop-registers" } */
+
+int v;
+int bar (int, int, int, int, int, int, int);
+
+int
+foo (void)
+{
+  return bar (0, 0, 0, 0, 0, 0, v > 0 ? v : 0);
+}