]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR tree-optimization/61634 (ICE in in vect_get_vec_def_for_operand,...
authorRichard Biener <rguenther@suse.de>
Thu, 26 Feb 2015 13:28:48 +0000 (13:28 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 26 Feb 2015 13:28:48 +0000 (13:28 +0000)
2015-02-26  Richard Biener  <rguenther@suse.de>

Backport from mainline
2014-11-27  Richard Biener  <rguenther@suse.de>

PR tree-optimization/61634
* tree-vect-slp.c: (vect_detect_hybrid_slp_stmts): Rewrite to
propagate hybrid down the SLP tree for one scalar statement.
(vect_detect_hybrid_slp_1): New walker function.
(vect_detect_hybrid_slp_2): Likewise.
(vect_detect_hybrid_slp): Properly handle pattern statements
in a pre-scan over all loop stmts.

* gcc.dg/vect/pr61634.c: New testcase.

From-SVN: r221006

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

index fa4587d77fd450ee033a4c99dce42286e0fe42a9..7dab0b3f624add2cd4206e2f51fa51e2b6d60dd5 100644 (file)
@@ -1,3 +1,16 @@
+2015-02-26  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2014-11-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/61634
+       * tree-vect-slp.c: (vect_detect_hybrid_slp_stmts): Rewrite to
+       propagate hybrid down the SLP tree for one scalar statement.
+       (vect_detect_hybrid_slp_1): New walker function.
+       (vect_detect_hybrid_slp_2): Likewise.
+       (vect_detect_hybrid_slp): Properly handle pattern statements
+       in a pre-scan over all loop stmts.
+
 2015-02-25  Georg-Johann Lay  <avr@gjlay.de>
 
        PR target/65196
index a83392918e1a53ff2b3ff89e07f9efa95d56d81d..9b87eb698cfb560a4d277bb5722d414a482aee29 100644 (file)
@@ -1,3 +1,11 @@
+2015-02-26  Richard Biener  <rguenther@suse.de>
+
+       Backport from mainline
+       2014-11-27  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/61634
+       * gcc.dg/vect/pr61634.c: New testcase.
+
 2015-02-25  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
diff --git a/gcc/testsuite/gcc.dg/vect/pr61634.c b/gcc/testsuite/gcc.dg/vect/pr61634.c
new file mode 100644 (file)
index 0000000..80b2c3a
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+int a, b, c, d;
+short *e;
+void fn1 (int p1[], int p2, int p3[], int p4[], int p5[], int *p6)
+{
+  int f;
+  c = *p1;
+  d = *p5;
+  (void)p6;
+  for (; a; a--)
+    {
+      f = *e >> 2;
+      *e++ = f;
+      b += f * f;
+      f = *e >> 2;
+      *e++ = f;
+    }
+  p4[0] = p3[0];
+  for (;; p2--)
+    ;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index d00a0d40b1fd4d9aa43908ae0e45086336e2f810..6405d8246970d3dedb2caa01d02337361081a56a 100644 (file)
@@ -1805,51 +1805,83 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
    can't be SLPed) in the tree rooted at NODE.  Mark such stmts as HYBRID.  */
 
 static void
-vect_detect_hybrid_slp_stmts (slp_tree node)
+vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype)
 {
-  int i;
-  vec<gimple> stmts = SLP_TREE_SCALAR_STMTS (node);
-  gimple stmt = stmts[0];
+  gimple stmt = SLP_TREE_SCALAR_STMTS (node)[i];
   imm_use_iterator imm_iter;
   gimple use_stmt;
-  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+  stmt_vec_info use_vinfo, stmt_vinfo = vinfo_for_stmt (stmt);
   slp_void_p child;
   loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
-  struct loop *loop = NULL;
-  bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
-  basic_block bb = NULL;
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  int j;
+
+  /* Propagate hybrid down the SLP tree.  */
+  if (stype == hybrid)
+    ;
+  else if (HYBRID_SLP_STMT (stmt_vinfo))
+    stype = hybrid;
+  else
+    {
+      /* Check if a pure SLP stmt has uses in non-SLP stmts.  */
+      gcc_checking_assert (PURE_SLP_STMT (stmt_vinfo));
+      if (TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
+       FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0))
+         if (gimple_bb (use_stmt)
+             && flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
+             && (use_vinfo = vinfo_for_stmt (use_stmt))
+             && !STMT_SLP_TYPE (use_vinfo)
+             && (STMT_VINFO_RELEVANT (use_vinfo)
+                 || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (use_vinfo))
+                 || (STMT_VINFO_IN_PATTERN_P (use_vinfo)
+                     && STMT_VINFO_RELATED_STMT (use_vinfo)
+                     && !STMT_SLP_TYPE (vinfo_for_stmt
+                                        (STMT_VINFO_RELATED_STMT (use_vinfo)))))
+             && !(gimple_code (use_stmt) == GIMPLE_PHI
+                  && STMT_VINFO_DEF_TYPE (use_vinfo) == vect_reduction_def))
+           stype = hybrid;
+    }
+
+  if (stype == hybrid)
+    STMT_SLP_TYPE (stmt_vinfo) = hybrid;
+
+  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
+    vect_detect_hybrid_slp_stmts ((slp_tree) child, i, stype);
+}
 
-  if (!node)
-    return;
+/* Helpers for vect_detect_hybrid_slp walking pattern stmt uses.  */
 
-  if (loop_vinfo)
-    loop = LOOP_VINFO_LOOP (loop_vinfo);
-  else
-    bb = BB_VINFO_BB (bb_vinfo);
+static tree
+vect_detect_hybrid_slp_1 (tree *tp, int *, void *data)
+{
+  walk_stmt_info *wi = (walk_stmt_info *)data;
+  struct loop *loopp = (struct loop *)wi->info;
 
-  FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt)
-    if (PURE_SLP_STMT (vinfo_for_stmt (stmt))
-       && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
-      FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0))
-       if (gimple_bb (use_stmt)
-            && ((loop && flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
-                || bb == gimple_bb (use_stmt))
-           && (stmt_vinfo = vinfo_for_stmt (use_stmt))
-           && !STMT_SLP_TYPE (stmt_vinfo)
-            && (STMT_VINFO_RELEVANT (stmt_vinfo)
-                || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_vinfo))
-               || (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)
-                   && STMT_VINFO_RELATED_STMT (stmt_vinfo)
-                   && !STMT_SLP_TYPE (vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_vinfo)))))
-           && !(gimple_code (use_stmt) == GIMPLE_PHI
-                 && STMT_VINFO_DEF_TYPE (stmt_vinfo)
-                  == vect_reduction_def))
-         vect_mark_slp_stmts (node, hybrid, i);
+  if (wi->is_lhs)
+    return NULL_TREE;
 
-  FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child)
-    vect_detect_hybrid_slp_stmts ((slp_tree) child);
+  if (TREE_CODE (*tp) == SSA_NAME
+      && !SSA_NAME_IS_DEFAULT_DEF (*tp))
+    {
+      gimple def_stmt = SSA_NAME_DEF_STMT (*tp);
+      if (flow_bb_inside_loop_p (loopp, gimple_bb (def_stmt))
+         && PURE_SLP_STMT (vinfo_for_stmt (def_stmt)))
+       STMT_SLP_TYPE (vinfo_for_stmt (def_stmt)) = hybrid;
+    }
+
+  return NULL_TREE;
 }
 
+static tree
+vect_detect_hybrid_slp_2 (gimple_stmt_iterator *gsi, bool *handled,
+                         walk_stmt_info *)
+{
+  /* If the stmt is in a SLP instance then this isn't a reason
+     to mark use definitions in other SLP instances as hybrid.  */
+  if (STMT_SLP_TYPE (vinfo_for_stmt (gsi_stmt (*gsi))) != loop_vect)
+    *handled = true;
+  return NULL_TREE;
+}
 
 /* Find stmts that must be both vectorized and SLPed.  */
 
@@ -1863,8 +1895,41 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
   if (dump_enabled_p ())
     dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ===");
 
+  /* First walk all pattern stmt in the loop and mark defs of uses as
+     hybrid because immediate uses in them are not recorded.  */
+  for (i = 0; i < LOOP_VINFO_LOOP (loop_vinfo)->num_nodes; ++i)
+    {
+      basic_block bb = LOOP_VINFO_BBS (loop_vinfo)[i];
+      for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
+          gsi_next (&gsi))
+       {
+         gimple stmt = gsi_stmt (gsi);
+         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+         if (STMT_VINFO_IN_PATTERN_P (stmt_info))
+           {
+             walk_stmt_info wi;
+             memset (&wi, 0, sizeof (wi));
+             wi.info = LOOP_VINFO_LOOP (loop_vinfo);
+             gimple_stmt_iterator gsi2
+               = gsi_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info));
+             walk_gimple_stmt (&gsi2, vect_detect_hybrid_slp_2,
+                               vect_detect_hybrid_slp_1, &wi);
+             walk_gimple_seq (STMT_VINFO_PATTERN_DEF_SEQ (stmt_info),
+                              vect_detect_hybrid_slp_2,
+                              vect_detect_hybrid_slp_1, &wi);
+           }
+       }
+    }
+
+  /* Then walk the SLP instance trees marking stmts with uses in
+     non-SLP stmts as hybrid, also propagating hybrid down the
+     SLP tree, collecting the above info on-the-fly.  */
   FOR_EACH_VEC_ELT (slp_instances, i, instance)
-    vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance));
+    {
+      for (unsigned i = 0; i < SLP_INSTANCE_GROUP_SIZE (instance); ++i)
+       vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance),
+                                     i, pure_slp);
+    }
 }