Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2018-09-19  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/87349
        PR tree-optimization/87342
        * tree-ssa-sccvn.c (do_rpo_vn): Iterate max_rpo computation.

        * gcc.dg/torture/pr87349-1.c: New testcase.
        * gcc.dg/torture/pr87349-2.c: Likewise.
        * gcc.dg/torture/pr87342.c: Likewise.

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        (revision 264390)
+++ gcc/tree-ssa-sccvn.c        (working copy)
@@ -6374,6 +6374,7 @@ do_rpo_vn (function *fn, edge entry, bit
   vn_valueize = rpo_vn_valueize;
 
   /* Initialize the unwind state and edge/BB executable state.  */
+  bool need_max_rpo_iterate = false;
   for (int i = 0; i < n; ++i)
     {
       basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
@@ -6388,11 +6389,14 @@ do_rpo_vn (function *fn, edge entry, bit
          if (e->flags & EDGE_DFS_BACK)
            has_backedges = true;
          e->flags &= ~EDGE_EXECUTABLE;
-         if (e == entry)
+         if (iterate || e == entry)
            continue;
          if (bb_to_rpo[e->src->index] > i)
-           rpo_state[i].max_rpo = MAX (rpo_state[i].max_rpo,
-                                       bb_to_rpo[e->src->index]);
+           {
+             rpo_state[i].max_rpo = MAX (rpo_state[i].max_rpo,
+                                         bb_to_rpo[e->src->index]);
+             need_max_rpo_iterate = true;
+           }
          else
            rpo_state[i].max_rpo
              = MAX (rpo_state[i].max_rpo,
@@ -6403,6 +6407,35 @@ do_rpo_vn (function *fn, edge entry, bit
   entry->flags |= EDGE_EXECUTABLE;
   entry->dest->flags |= BB_EXECUTABLE;
 
+  /* When there are irreducible regions the simplistic max_rpo computation
+     above for the case of backedges doesn't work and we need to iterate
+     until there are no more changes.  */
+  unsigned nit = 0;
+  while (need_max_rpo_iterate)
+    {
+      nit++;
+      need_max_rpo_iterate = false;
+      for (int i = 0; i < n; ++i)
+       {
+         basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
+         edge e;
+         edge_iterator ei;
+         FOR_EACH_EDGE (e, ei, bb->preds)
+           {
+             if (e == entry)
+               continue;
+             int max_rpo = MAX (rpo_state[i].max_rpo,
+                                rpo_state[bb_to_rpo[e->src->index]].max_rpo);
+             if (rpo_state[i].max_rpo != max_rpo)
+               {
+                 rpo_state[i].max_rpo = max_rpo;
+                 need_max_rpo_iterate = true;
+               }
+           }
+       }
+    }
+  statistics_histogram_event (cfun, "RPO max_rpo iterations", nit);
+
   /* As heuristic to improve compile-time we handle only the N innermost
      loops and the outermost one optimistically.  */
   if (iterate)
Index: gcc/testsuite/gcc.dg/torture/pr87349-1.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr87349-1.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr87349-1.c    (working copy)
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+
+void
+h1 (int *fh, int pw)
+{
+  *fh = 0;
+  if (*fh != 0)
+    for (;;)
+      {
+       fh = &pw;
+
+       if (pw == 0)
+         {
+         }
+       else
+         while (pw < 1)
+           {
+             if (pw == 0)
+               {
+ut:
+                 ;
+               }
+
+             ++pw;
+           }
+
+       if (pw == 0)
+         goto ut;
+      }
+
+  goto ut;
+}
+
Index: gcc/testsuite/gcc.dg/torture/pr87349-2.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr87349-2.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr87349-2.c    (working copy)
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+
+void
+h1 (int *fh, int pw)
+{
+  *fh = 0;
+  if (*fh != 0)
+    for (;;)
+      {
+       fh = &pw;
+
+       if (pw == 0)
+         {
+         }
+       else
+         while (pw < 1)
+           {
+             if (pw == 0)
+               {
+ut:
+                 ;
+               }
+
+             ++pw;
+           }
+
+       if (pw == *fh)
+         goto ut;
+      }
+
+  goto ut;
+}
+
Index: gcc/testsuite/gcc.dg/torture/pr87342.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr87342.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr87342.c      (working copy)
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+
+int ix;
+
+void
+o6 (int rh)
+{
+  if (rh == 0)
+    {
+      ix = 0;
+      while (ix < 1)
+       {
+       }
+
+      for (;;)
+       if (ix == 0)
+         while (rh < 1)
+           {
+             if (rh == 0)
+               {
+                 __builtin_unreachable ();
+
+kp:
+                 if (ix == 0)
+                   {
+hk:
+                     ix = 0;
+                   }
+               }
+
+             while (rh < 1)
+               if (ix == 0)
+                 goto kp;
+
+             while (rh < 1)
+               {
+               }
+           }
+       else
+         goto kp;
+    }
+
+  goto hk;
+}

Reply via email to