re PR tree-optimization/87147 (GCC miscompiles at -O3 on valid code)
authorRichard Biener <rguenther@suse.de>
Thu, 30 Aug 2018 12:37:10 +0000 (12:37 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 30 Aug 2018 12:37:10 +0000 (12:37 +0000)
2018-08-30  Richard Biener  <rguenther@suse.de>

PR tree-optimization/87147
* tree-ssa-sccvn.c (SSA_VISITED): New function.
(visit_phi): When the degenerate result is from the backedge and
we didn't visit its definition yet drop to VARYING.
(do_rpo_vn): Properly mark blocks with incoming backedges as executable.

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

From-SVN: r263980

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr87147.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 0349cdc919d2af0c2d6b3b8bf3a049ab8e7dcd4c..e7a1910ee6ff8556c3d5b1a0ad1225b8a028b344 100644 (file)
@@ -1,3 +1,11 @@
+2018-08-30  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87147
+       * tree-ssa-sccvn.c (SSA_VISITED): New function.
+       (visit_phi): When the degenerate result is from the backedge and
+       we didn't visit its definition yet drop to VARYING.
+       (do_rpo_vn): Properly mark blocks with incoming backedges as executable.
+
 2018-08-29  Jan Hubicka  <jh@suse.cz>
 
        * lto-streamer-out.c (DFS::DFS_write_tree_body): Do not walk
index fd78dcf089207eafce38ea15e4cdcaa0847db991..75e6c6755638dd87cf03ad624a2748752541b785 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-30  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87147
+       * gcc.dg/torture/pr87147.c: New testcase.
+
 2018-08-30  Tamar Christina  <tamar.christina@arm.com>
 
        * gcc.target/aarch64/large_struct_copy_2.c: New.
diff --git a/gcc/testsuite/gcc.dg/torture/pr87147.c b/gcc/testsuite/gcc.dg/torture/pr87147.c
new file mode 100644 (file)
index 0000000..385cfce
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+short a;
+long b;
+int c, d, g;
+char e, h;
+long f[] = {0};
+int main()
+{
+  int i = 1;
+  for (; a <= 3; a++) {
+      c = 0;
+      for (; c <= 2; c++) {
+         b = 0;
+         for (; b <= 3; b++) {
+             h = i && f[d];
+             e = g && i;
+             i = 0;
+         }
+      }
+  }
+}
index 39ab4b252858d5b6e0f672beb5b5d1d764008429..2bf71e5b15b359a7debd12194e74a759cf85f554 100644 (file)
@@ -462,6 +462,15 @@ SSA_VAL (tree x)
   return tem && tem->visited ? tem->valnum : x;
 }
 
+/* Return whether X was visited.  */
+
+inline bool
+SSA_VISITED (tree x)
+{
+  vn_ssa_aux_t tem = vn_ssa_aux_hash->find_with_hash (x, SSA_NAME_VERSION (x));
+  return tem && tem->visited;
+}
+
 /* Return the SSA value of the VUSE x, supporting released VDEFs
    during elimination which will value-number the VDEF to the
    associated VUSE (but not substitute in the whole lattice).  */
@@ -4100,6 +4109,7 @@ static bool
 visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
 {
   tree result, sameval = VN_TOP, seen_undef = NULL_TREE;
+  tree backedge_name = NULL_TREE;
   tree sameval_base = NULL_TREE;
   poly_int64 soff, doff;
   unsigned n_executable = 0;
@@ -4126,9 +4136,13 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
        tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
 
        ++n_executable;
-       if (TREE_CODE (def) == SSA_NAME
-           && (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK)))
-         def = SSA_VAL (def);
+       if (TREE_CODE (def) == SSA_NAME)
+         {
+           if (e->flags & EDGE_DFS_BACK)
+             backedge_name = def;
+           if (!backedges_varying_p || !(e->flags & EDGE_DFS_BACK))
+             def = SSA_VAL (def);
+         }
        if (def == VN_TOP)
          ;
        /* Ignore undefined defs for sameval but record one.  */
@@ -4162,10 +4176,15 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p)
          }
       }
 
-
+  /* If the value we want to use is the backedge and that wasn't visited
+     yet drop to VARYING.  */ 
+  if (backedge_name
+      && sameval == backedge_name
+      && !SSA_VISITED (backedge_name))
+    result = PHI_RESULT (phi);
   /* If none of the edges was executable keep the value-number at VN_TOP,
      if only a single edge is exectuable use its value.  */
-  if (n_executable <= 1)
+  else if (n_executable <= 1)
     result = seen_undef ? seen_undef : sameval;
   /* If we saw only undefined values and VN_TOP use one of the
      undefined values.  */
@@ -6298,6 +6317,7 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
     {
       basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
       rpo_state[i].visited = 0;
+      bb->flags &= ~BB_EXECUTABLE;
       bool has_backedges = false;
       edge e;
       edge_iterator ei;
@@ -6306,12 +6326,17 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
          if (e->flags & EDGE_DFS_BACK)
            has_backedges = true;
          if (! iterate && (e->flags & EDGE_DFS_BACK))
-           e->flags |= EDGE_EXECUTABLE;
+           {
+             e->flags |= EDGE_EXECUTABLE;
+             /* ???  Strictly speaking we only need to unconditionally
+                process a block when it is in an irreducible region,
+                thus when it may be reachable via the backedge only.  */
+             bb->flags |= BB_EXECUTABLE;
+           }
          else
            e->flags &= ~EDGE_EXECUTABLE;
        }
       rpo_state[i].iterate = iterate && has_backedges;
-      bb->flags &= ~BB_EXECUTABLE;
     }
   entry->flags |= EDGE_EXECUTABLE;
   entry->dest->flags |= BB_EXECUTABLE;