re PR tree-optimization/87790 (ICE in vect_get_vec_def_for_operand_1, at tree-vect...
authorRichard Biener <rguenther@suse.de>
Mon, 29 Oct 2018 14:57:52 +0000 (14:57 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 29 Oct 2018 14:57:52 +0000 (14:57 +0000)
2018-10-29  Richard Biener  <rguenther@suse.de>

PR tree-optimization/87790
* tree-vect-slp.c (vect_mark_slp_stmts): Simplify.
(vect_make_slp_decision): Adjust.
(vect_slp_analyze_bb_1): Likewise.
(vect_detect_hybrid_slp_stmts): Properly union SLP type over
edges.

* gcc.dg/pr87790.c: New testcase.

From-SVN: r265593

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr87790.c [new file with mode: 0644]
gcc/tree-vect-slp.c

index 5bb718838de1bb0b812f23dfcbf84fb2aa0c7535..14eee689ce2e8e02456dfdee4953d17af4c0431b 100644 (file)
@@ -1,3 +1,12 @@
+2018-10-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87790
+       * tree-vect-slp.c (vect_mark_slp_stmts): Simplify.
+       (vect_make_slp_decision): Adjust.
+       (vect_slp_analyze_bb_1): Likewise.
+       (vect_detect_hybrid_slp_stmts): Properly union SLP type over
+       edges.
+
 2018-10-29  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/87785
index 5584b886f1dcd52e46809e61e95fad3fdc325198..fa6d53717ab154823f3abd563c2c2547258bf58a 100644 (file)
@@ -1,3 +1,8 @@
+2018-10-29  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87790
+       * gcc.dg/pr87790.c: New testcase.
+
 2018-10-29  Martin Liska  <mliska@suse.cz>
 
        * g++.dg/gcov/gcov-8.C: Do not check intermediate format.
diff --git a/gcc/testsuite/gcc.dg/pr87790.c b/gcc/testsuite/gcc.dg/pr87790.c
new file mode 100644 (file)
index 0000000..4fa1486
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-profiling "-fprofile-generate" } */
+/* { dg-options "-Ofast -fprofile-generate" } */
+/* { dg-additional-options "-march=znver1" { target { x86_64-*-* i?86-*-* } } } */
+
+int a, b;
+void c(int d[][8])
+{
+  int e, f;
+  for (; b; b++) {
+    e = d[b][0] % 4 * 21;
+    if (e >= 21)
+      e--;
+    a = d[b][0] - e;
+    f = 1;
+    for (; f != 8; f++)
+      d[b][f] = a;
+  }
+}
index 7bb0d3aa0e0af59004293ce8998b5fb9a496478d..a1db0dfde86e44ee5ce6d1b55914e733f4457fe6 100644 (file)
@@ -1469,14 +1469,10 @@ vect_print_slp_tree (dump_flags_t dump_kind, dump_location_t loc,
   vect_print_slp_tree (dump_kind, loc, node, visited);
 }
 
-/* Mark the tree rooted at NODE with MARK (PURE_SLP or HYBRID).
-   If MARK is HYBRID, it refers to a specific stmt in NODE (the stmt at index
-   J).  Otherwise, MARK is PURE_SLP and J is -1, which indicates that all the
-   stmts in NODE are to be marked.  */
+/* Mark the tree rooted at NODE with PURE_SLP.  */
 
 static void
-vect_mark_slp_stmts (slp_tree node, enum slp_vect_type mark, int j,
-                    hash_set<slp_tree> &visited)
+vect_mark_slp_stmts (slp_tree node, hash_set<slp_tree> &visited)
 {
   int i;
   stmt_vec_info stmt_info;
@@ -1489,18 +1485,17 @@ vect_mark_slp_stmts (slp_tree node, enum slp_vect_type mark, int j,
     return;
 
   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
-    if (j < 0 || i == j)
-      STMT_SLP_TYPE (stmt_info) = mark;
+    STMT_SLP_TYPE (stmt_info) = pure_slp;
 
   FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
-    vect_mark_slp_stmts (child, mark, j, visited);
+    vect_mark_slp_stmts (child, visited);
 }
 
 static void
-vect_mark_slp_stmts (slp_tree node, enum slp_vect_type mark, int j)
+vect_mark_slp_stmts (slp_tree node)
 {
   hash_set<slp_tree> visited;
-  vect_mark_slp_stmts (node, mark, j, visited);
+  vect_mark_slp_stmts (node, visited);
 }
 
 /* Mark the statements of the tree rooted at NODE as relevant (vect_used).  */
@@ -2216,7 +2211,7 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
       /* Mark all the stmts that belong to INSTANCE as PURE_SLP stmts.  Later we
         call vect_detect_hybrid_slp () to find stmts that need hybrid SLP and
         loop-based vectorization.  Such stmts will be marked as HYBRID.  */
-      vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance), pure_slp, -1);
+      vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance));
       decided_to_slp++;
     }
 
@@ -2240,7 +2235,7 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
 
 static void
 vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype,
-                             hash_set<slp_tree> &visited)
+                             hash_map<slp_tree, unsigned> &visited)
 {
   stmt_vec_info stmt_vinfo = SLP_TREE_SCALAR_STMTS (node)[i];
   imm_use_iterator imm_iter;
@@ -2250,15 +2245,16 @@ vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype,
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
   int j;
 
-  if (visited.add (node))
-    return;
+  /* We need to union stype over the incoming graph edges but we still
+     want to limit recursion to stay O(N+E).  */
+  bool only_edge = (++visited.get_or_insert (node) < node->refcnt);
 
   /* Propagate hybrid down the SLP tree.  */
   if (stype == hybrid)
     ;
   else if (HYBRID_SLP_STMT (stmt_vinfo))
     stype = hybrid;
-  else
+  else if (!only_edge)
     {
       /* Check if a pure SLP stmt has uses in non-SLP stmts.  */
       gcc_checking_assert (PURE_SLP_STMT (stmt_vinfo));
@@ -2300,15 +2296,16 @@ vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype,
       STMT_SLP_TYPE (stmt_vinfo) = hybrid;
     }
 
-  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
-    if (SLP_TREE_DEF_TYPE (child) != vect_external_def)
-      vect_detect_hybrid_slp_stmts (child, i, stype, visited);
+  if (!only_edge)
+    FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
+      if (SLP_TREE_DEF_TYPE (child) != vect_external_def)
+       vect_detect_hybrid_slp_stmts (child, i, stype, visited);
 }
 
 static void
 vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype)
 {
-  hash_set<slp_tree> visited;
+  hash_map<slp_tree, unsigned> visited;
   vect_detect_hybrid_slp_stmts (node, i, stype, visited);
 }
 
@@ -2894,7 +2891,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
 
       /* Mark all the statements that we want to vectorize as pure SLP and
         relevant.  */
-      vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance), pure_slp, -1);
+      vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance));
       vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance));
 
       i++;