Hi,

We have this code in sel-sched.c sel_region_init():

6918   /* Init correct liveness sets on each instruction of a single-block loop.
6919      This is the only situation when we can't update liveness when calling
6920      compute_live for the first insn of the loop.  */
6921   if (current_loop_nest)
6922     {
6923       int header =
6924         (sel_is_loop_preheader_p (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK 
(0)))
6925          ? 1
6926          : 0);
6927
6928       if (current_nr_blocks == header + 1)
6929         update_liveness_on_insn
6930           (sel_bb_head (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (header))));
6931     }

It appears it does not account for presence of empty BBs between the preheader
and the "actual header" BB hosting the first insn of the loop. The testcase in
the PR provides an example where we don't run update_liveness_on_insn here, but
then remove the empty BB and recurse endlessly in compute_live_after_bb.

This patch solves this in a brute-but-straightforward manner by invoking
cleanup_cfg just before loop_optimizer_init.

Bootstrapped/regtested on x86_64 together with the other two patches and also
checked on a powerpc cross-compiler that the testcase is fixed. OK to apply?

Thanks.
Alexander

        PR rtl-optimization/85659
        * sel-sched-ir.c (sel_init_pipelining): Invoke cleanup_cfg.

        * gcc.dg/pr84659.c: New test.


diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index ee970522890..aef380a7e80 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgrtl.h"
 #include "cfganal.h"
 #include "cfgbuild.h"
+#include "cfgcleanup.h"
 #include "insn-config.h"
 #include "insn-attr.h"
 #include "recog.h"
@@ -6121,6 +6122,7 @@ make_regions_from_loop_nest (struct loop *loop)
 void
 sel_init_pipelining (void)
 {
+  cleanup_cfg (0);
   /* Collect loop information to be used in outer loops pipelining.  */
   loop_optimizer_init (LOOPS_HAVE_PREHEADERS
                        | LOOPS_HAVE_FALLTHRU_PREHEADERS
diff --git a/gcc/testsuite/gcc.dg/pr84659.c b/gcc/testsuite/gcc.dg/pr84659.c
index e69de29bb2d..94c885f3869 100644
--- a/gcc/testsuite/gcc.dg/pr84659.c
+++ b/gcc/testsuite/gcc.dg/pr84659.c
@@ -0,0 +1,19 @@
+/* PR rtl-optimization/84659 */
+/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fselective-scheduling -fsel-sched-pipelining 
-fno-split-wide-types -fno-strict-aliasing -fno-tree-dce" } */
+
+void
+jk (int **lq, int *k4, long long int qv, int od)
+{
+  while (**lq < 1)
+    {
+      int uo;
+
+      uo = ((od == 0) ? qv : *k4) != 1;
+      ++**lq;
+    }
+
+  for (;;)
+    {
+    }
+}

Reply via email to