]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix phi backedge detection in backprop (PR85989)
authorRichard Sandiford <richard.sandiford@linaro.org>
Sat, 23 Jun 2018 16:18:36 +0000 (16:18 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 23 Jun 2018 16:18:36 +0000 (16:18 +0000)
Backport trunk r261064.

2018-06-23  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
PR tree-optimization/85989
* gimple-ssa-backprop.c (backprop::m_visited_phis): New member
variable.
(backprop::backprop): Initialize it.
(backprop::~backprop): Free it.
(backprop::intersect_uses): Check it when deciding whether this
is a backedge reference.
(backprop::process_block): Add each phi to m_visited_phis
after visiting it, then clear it at the end.

gcc/testsuite/
PR tree-optimization/85989
* gcc.dg/torture/pr85989.c: New test.

From-SVN: r261985

gcc/ChangeLog
gcc/gimple-ssa-backprop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr85989.c [new file with mode: 0644]

index 0a6094e4a63f6ae49b21c5d1124b26ebd37a9a9a..3ec50a873c001f95b072cc1b9c827f513af94fce 100644 (file)
@@ -1,3 +1,15 @@
+2018-06-23  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR tree-optimization/85989
+       * gimple-ssa-backprop.c (backprop::m_visited_phis): New member
+       variable.
+       (backprop::backprop): Initialize it.
+       (backprop::~backprop): Free it.
+       (backprop::intersect_uses): Check it when deciding whether this
+       is a backedge reference.
+       (backprop::process_block): Add each phi to m_visited_phis
+       after visiting it, then clear it at the end.
+
 2018-06-21  Richard Biener  <rguenther@suse.de>
  
        Backport from mainline
index d96bccac555f5fedfc5ceb08b1a7e8e672ccd1b6..2677611226277665893dd98c99a7506e0c4d8b8a 100644 (file)
@@ -260,6 +260,11 @@ private:
      post-order walk.  */
   sbitmap m_visited_blocks;
 
+  /* A bitmap of phis that we have finished processing in the initial
+     post-order walk, excluding those from blocks mentioned in
+     M_VISITED_BLOCKS.  */
+  bitmap m_visited_phis;
+
   /* A worklist of SSA names whose definitions need to be reconsidered.  */
   auto_vec <tree, 64> m_worklist;
 
@@ -273,6 +278,7 @@ backprop::backprop (function *fn)
   : m_fn (fn),
     m_info_pool ("usage_info"),
     m_visited_blocks (sbitmap_alloc (last_basic_block_for_fn (m_fn))),
+    m_visited_phis (BITMAP_ALLOC (NULL)),
     m_worklist_names (BITMAP_ALLOC (NULL))
 {
   bitmap_clear (m_visited_blocks);
@@ -281,6 +287,7 @@ backprop::backprop (function *fn)
 backprop::~backprop ()
 {
   BITMAP_FREE (m_worklist_names);
+  BITMAP_FREE (m_visited_phis);
   sbitmap_free (m_visited_blocks);
   m_info_pool.release ();
 }
@@ -501,8 +508,11 @@ backprop::intersect_uses (tree var, usage_info *info)
     {
       if (is_gimple_debug (stmt))
        continue;
-      if (is_a <gphi *> (stmt)
-         && !bitmap_bit_p (m_visited_blocks, gimple_bb (stmt)->index))
+      gphi *phi = dyn_cast <gphi *> (stmt);
+      if (phi
+         && !bitmap_bit_p (m_visited_blocks, gimple_bb (phi)->index)
+         && !bitmap_bit_p (m_visited_phis,
+                           SSA_NAME_VERSION (gimple_phi_result (phi))))
        {
          /* Skip unprocessed phis.  */
          if (dump_file && (dump_flags & TDF_DETAILS))
@@ -510,7 +520,7 @@ backprop::intersect_uses (tree var, usage_info *info)
              fprintf (dump_file, "[BACKEDGE] ");
              print_generic_expr (dump_file, var, 0);
              fprintf (dump_file, " in ");
-             print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+             print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
            }
        }
       else
@@ -634,7 +644,12 @@ backprop::process_block (basic_block bb)
     }
   for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi);
        gsi_next (&gpi))
-    process_var (gimple_phi_result (gpi.phi ()));
+    {
+      tree result = gimple_phi_result (gpi.phi ());
+      process_var (result);
+      bitmap_set_bit (m_visited_phis, SSA_NAME_VERSION (result));
+    }
+  bitmap_clear (m_visited_phis);
 }
 
 /* Delete the definition of VAR, which has no uses.  */
index 19a35ad13deb548be5f684a08d3f2b595de9ab7c..4b40b0e5631b090ef871d507e45f568422195f34 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-23  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       PR tree-optimization/85989
+       * gcc.dg/torture/pr85989.c: New test.
+
 2018-06-21  Richard Biener  <rguenther@suse.de>
  
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/torture/pr85989.c b/gcc/testsuite/gcc.dg/torture/pr85989.c
new file mode 100644 (file)
index 0000000..5cfd701
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+#define N 9
+
+void __attribute__((noinline, noclone))
+f (double x, double y, double *res)
+{
+  y = -y;
+  for (int i = 0; i < N; ++i)
+    {
+      double tmp = y;
+      y = x;
+      x = tmp;
+      res[i] = i;
+    }
+  res[N] = y * y;
+  res[N + 1] = x;
+}
+
+int
+main (void)
+{
+  double res[N + 2];
+  f (10, 20, res);
+  for (int i = 0; i < N; ++i)
+    if (res[i] != i)
+      __builtin_abort ();
+  if (res[N] != 100 || res[N + 1] != -20)
+    __builtin_abort ();
+  return 0;
+}