aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-11-27 09:33:32 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-11-27 09:33:32 +0000
commit642fce57a7208339a4f55ff8c3ce377a2cfa4738 (patch)
tree73af2fc6f50518b9204c2c22955efa0f2226accd /gcc
parent22273d1adbff93ebca70943be269e89d094c12e3 (diff)
downloadgcc-642fce57a7208339a4f55ff8c3ce377a2cfa4738.zip
gcc-642fce57a7208339a4f55ff8c3ce377a2cfa4738.tar.gz
gcc-642fce57a7208339a4f55ff8c3ce377a2cfa4738.tar.bz2
re PR tree-optimization/61634 (ICE in in vect_get_vec_def_for_operand, at tree-vect-stmts.c:1423)
2014-11-27 Richard Biener <rguenther@suse.de> PR tree-optimization/61634 * tree-vect-slp.c: Include gimple-walk.h. (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: r218113
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr61634.c24
-rw-r--r--gcc/tree-vect-slp.c136
4 files changed, 141 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 515128f..26b4720 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2014-11-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/61634
+ * tree-vect-slp.c: Include gimple-walk.h.
+ (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.
+
2014-11-27 Zhenqiang Chen <zhenqiang.chen@linaro.org>
Revert:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b96e698..5e671fa 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/61634
+ * gcc.dg/vect/pr61634.c: New testcase.
+
2014-11-26 David Edelsohn <dje.gcc@gmail.com>
* g++.dg/ext/alignof2.C: xfail-run-if on AIX.
diff --git a/gcc/testsuite/gcc.dg/vect/pr61634.c b/gcc/testsuite/gcc.dg/vect/pr61634.c
new file mode 100644
index 0000000..80b2c3a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr61634.c
@@ -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" } } */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 829f74a..270423d 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h"
#include "tree-vectorizer.h"
#include "langhooks.h"
+#include "gimple-walk.h"
/* Extract the location of the basic block in the source code.
Return the basic block location if succeed and NULL if not. */
@@ -1829,51 +1830,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_tree 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 (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 (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. */
@@ -1888,8 +1921,41 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ==="
"\n");
+ /* 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);
+ }
}