Commit 642fce57 by Richard Biener Committed by Richard Biener

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
parent 22273d1a
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> 2014-11-27 Zhenqiang Chen <zhenqiang.chen@linaro.org>
Revert: Revert:
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> 2014-11-26 David Edelsohn <dje.gcc@gmail.com>
* g++.dg/ext/alignof2.C: xfail-run-if on AIX. * g++.dg/ext/alignof2.C: xfail-run-if on AIX.
......
/* { 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" } } */
...@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h" #include "optabs.h"
#include "tree-vectorizer.h" #include "tree-vectorizer.h"
#include "langhooks.h" #include "langhooks.h"
#include "gimple-walk.h"
/* Extract the location of the basic block in the source code. /* Extract the location of the basic block in the source code.
Return the basic block location if succeed and NULL if not. */ Return the basic block location if succeed and NULL if not. */
...@@ -1829,51 +1830,83 @@ vect_make_slp_decision (loop_vec_info loop_vinfo) ...@@ -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. */ can't be SLPed) in the tree rooted at NODE. Mark such stmts as HYBRID. */
static void 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; gimple stmt = SLP_TREE_SCALAR_STMTS (node)[i];
vec<gimple> stmts = SLP_TREE_SCALAR_STMTS (node);
gimple stmt = stmts[0];
imm_use_iterator imm_iter; imm_use_iterator imm_iter;
gimple use_stmt; 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; slp_tree child;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = NULL; struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo); int j;
basic_block bb = NULL;
/* 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) /* Helpers for vect_detect_hybrid_slp walking pattern stmt uses. */
return;
if (loop_vinfo) static tree
loop = LOOP_VINFO_LOOP (loop_vinfo); vect_detect_hybrid_slp_1 (tree *tp, int *, void *data)
else {
bb = BB_VINFO_BB (bb_vinfo); 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 (wi->is_lhs)
if (PURE_SLP_STMT (vinfo_for_stmt (stmt)) return NULL_TREE;
&& 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);
FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), i, child) if (TREE_CODE (*tp) == SSA_NAME
vect_detect_hybrid_slp_stmts (child); && !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. */ /* Find stmts that must be both vectorized and SLPed. */
...@@ -1888,8 +1921,41 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo) ...@@ -1888,8 +1921,41 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ===" dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ==="
"\n"); "\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) 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);
}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment