This should fix the endless PRE antic iterations for good.  OK, it's
somewhat of a hack but unless I fix another two or three parts of the
antic algorithm to not prune values that may later re-appear I see
no other way to guarantee this.  And this isn't the time to fiddle
with PRE further...

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

The assert I added previously is now defunct for CFG cycles which
makes it useless, I'll rip it out as a followup.

Richard.

2018-03-13  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/84830
        * tree-ssa-pre.c (compute_antic_aux): Intersect the new ANTIC_IN
        with the old one to avoid oscillations.

        * gcc.dg/torture/pr84830.c: New testcase.

Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c  (revision 258480)
+++ gcc/tree-ssa-pre.c  (working copy)
@@ -2154,6 +2154,35 @@ compute_antic_aux (basic_block block, bo
   /* clean (ANTIC_IN (block)) is defered to after the iteration converged
      because it can cause non-convergence, see for example PR81181.  */
 
+  /* Intersect ANTIC_IN with the old ANTIC_IN.  This is required until
+     we properly represent the maximum expression set, thus not prune
+     values without expressions during the iteration.  */
+  if (was_visited
+      && bitmap_and_into (&ANTIC_IN (block)->values, &old->values))
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+       fprintf (dump_file, "warning: intersecting with old ANTIC_IN "
+                "shrinks the set\n");
+      /* Prune expressions not in the value set.  */
+      bitmap_iterator bi;
+      unsigned int i;
+      unsigned int to_clear = -1U;
+      FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (block), i, bi)
+       {
+         if (to_clear != -1U)
+           {
+             bitmap_clear_bit (&ANTIC_IN (block)->expressions, to_clear);
+             to_clear = -1U;
+           }
+         pre_expr expr = expression_for_id (i);
+         unsigned int value_id = get_expr_value_id (expr);
+         if (!bitmap_bit_p (&ANTIC_IN (block)->values, value_id))
+           to_clear = i;
+       }
+      if (to_clear != -1U)
+       bitmap_clear_bit (&ANTIC_IN (block)->expressions, to_clear);
+    }
+
   if (!bitmap_set_equal (old, ANTIC_IN (block)))
     {
       changed = true;
Index: gcc/testsuite/gcc.dg/torture/pr84830.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr84830.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr84830.c      (working copy)
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-tree-ch -fno-tree-vrp" } */
+
+int x0;
+
+void
+br (int yp, int oo)
+{
+  int *qi = &yp;
+
+  if (oo == 0)
+    {
+g8:
+      if (x0 != 0)
+       x0 = yp;
+      else if (oo != 0)
+       x0 = yp;
+
+      if (x0 == 0)
+       {
+         *qi = 0;
+         x0 = *qi;
+       }
+
+      if (x0 != 0)
+       {
+         ++oo;
+         goto g8;
+       }
+
+      if (yp == oo)
+       yp += !!oo;
+    }
+  else
+    {
+      x0 = 1;
+      while (x0 < 2)
+       {
+         qi = &oo;
+         ++oo;
+         x0 = 1;
+       }
+    }
+
+  goto g8;
+}

Reply via email to