re PR tree-optimization/78856 (wrong code at -O3 on x86_64-linux-gnu (in both 32...
authorJeff Law <law@redhat.com>
Wed, 4 Jan 2017 05:31:23 +0000 (22:31 -0700)
committerJeff Law <law@gcc.gnu.org>
Wed, 4 Jan 2017 05:31:23 +0000 (22:31 -0700)
PR tree-optimizatin/78856
* tree-ssa-threadupdate.c: Include tree-vectorizer.h.
(mark_threaded_blocks): Remove code to truncate thread paths that
cross multiple loop headers.  Instead invalidate the cached loop
iteration information and handle case of a thread path walking
into an irreducible region.

PR tree-optimization/78856
* gcc.c-torture/execute/pr78856.c: New test.

From-SVN: r244045

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr78856.c [new file with mode: 0644]
gcc/tree-ssa-threadupdate.c

index 3114e02af6734b35ac409c0332b0ad396b08dbb4..6b2888f36f6e0e216f6e610f1507b068f3410b48 100644 (file)
@@ -1,3 +1,12 @@
+2017-01-03  Jeff Law  <law@redhat.com>
+
+       PR tree-optimizatin/78856
+       * tree-ssa-threadupdate.c: Include tree-vectorizer.h.
+       (mark_threaded_blocks): Remove code to truncate thread paths that
+       cross multiple loop headers.  Instead invalidate the cached loop
+       iteration information and handle case of a thread path walking
+       into an irreducible region.
+
 2016-12-30  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/78900
index cd2a065ec14cf55164c00157ef41ea50c1e8d147..cadfbc977ce4804fa0cc681860711670a303cf7d 100644 (file)
@@ -1,3 +1,8 @@
+2017-01-03  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/78856
+       * gcc.c-torture/execute/pr78856.c: New test.
+
 2017-01-03  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/78953
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78856.c b/gcc/testsuite/gcc.c-torture/execute/pr78856.c
new file mode 100644 (file)
index 0000000..80f2317
--- /dev/null
@@ -0,0 +1,25 @@
+extern void exit (int);
+
+int a, b, c, d, e, f[3]; 
+
+int main() 
+{
+  while (d)
+    while (1)
+      ;
+  int g = 0, h, i = 0;
+  for (; g < 21; g += 9) 
+    {
+      int j = 1;
+      for (h = 0; h < 3; h++)
+       f[h] = 1;
+      for (; j < 10; j++) {
+       d = i && (b ? 0 : c); 
+       i = 1;
+       if (g)
+         a = e;
+      }
+  }
+  exit (0);
+}
+
index adbb6e01c3ff490e390a80280294dad4cac3b08c..2da93a803d4762128ba66529ca3b987618b272d2 100644 (file)
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 #include "dbgcnt.h"
 #include "tree-cfg.h"
+#include "tree-vectorizer.h"
 
 /* Given a block B, update the CFG and SSA graph to reflect redirecting
    one or more in-edges to B to instead reach the destination of an
@@ -2084,10 +2085,8 @@ mark_threaded_blocks (bitmap threaded_blocks)
   /* Look for jump threading paths which cross multiple loop headers.
 
      The code to thread through loop headers will change the CFG in ways
-     that break assumptions made by the loop optimization code.
-
-     We don't want to blindly cancel the requests.  We can instead do better
-     by trimming off the end of the jump thread path.  */
+     that invalidate the cached loop iteration information.  So we must
+     detect that case and wipe the cached information.  */
   EXECUTE_IF_SET_IN_BITMAP (tmp, 0, i, bi)
     {
       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
@@ -2102,26 +2101,16 @@ mark_threaded_blocks (bitmap threaded_blocks)
                   i++)
                {
                  basic_block dest = (*path)[i]->e->dest;
+                 basic_block src = (*path)[i]->e->src;
                  crossed_headers += (dest == dest->loop_father->header);
+                 /* If we step from a block outside an irreducible region
+                    to a block inside an irreducible region, then we have
+                    crossed into a loop.  */
+                 crossed_headers += ((src->flags & BB_IRREDUCIBLE_LOOP)
+                                     != (dest->flags & BB_IRREDUCIBLE_LOOP));
                  if (crossed_headers > 1)
                    {
-                     /* Trim from entry I onwards.  */
-                     for (unsigned int j = i; j < path->length (); j++)
-                       delete (*path)[j];
-                     path->truncate (i);
-
-                     /* Now that we've truncated the path, make sure
-                        what's left is still valid.   We need at least
-                        two edges on the path and the last edge can not
-                        be a joiner.  This should never happen, but let's
-                        be safe.  */
-                     if (path->length () < 2
-                         || (path->last ()->type
-                             == EDGE_COPY_SRC_JOINER_BLOCK))
-                       {
-                         delete_jump_thread_path (path);
-                         e->aux = NULL;
-                       }
+                     vect_free_loop_info_assumptions (dest->loop_father);
                      break;
                    }
                }