Commit 22692f3c by Richard Biener Committed by Richard Biener

re PR tree-optimization/88031 (ICE in vectorizable_reduction, at tree-vect-loop.c:6953)

2018-11-15  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/88031
	* tree-vect-loop.c (vectorizable_reduction): Move check
	for multiple types earlier so we get the expected dump.
	Simplify calls to vectorizable_condition.
	* tree-vect-stmts.h (vectorizable_condition): Update prototype.
	* tree-vect-stmts.c (vectorizable_condition): Instead of
	reduc_def and reduc_index take just a flag.  Simplify
	code-generation now that we can rely on the defs being set up.
	(vectorizable_comparison): Remove unused argument.

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

From-SVN: r266182
parent 3f5a0fde
2018-11-15 Richard Biener <rguenther@suse.de> 2018-11-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/88031
* tree-vect-loop.c (vectorizable_reduction): Move check
for multiple types earlier so we get the expected dump.
Simplify calls to vectorizable_condition.
* tree-vect-stmts.h (vectorizable_condition): Update prototype.
* tree-vect-stmts.c (vectorizable_condition): Instead of
reduc_def and reduc_index take just a flag. Simplify
code-generation now that we can rely on the defs being set up.
(vectorizable_comparison): Remove unused argument.
2018-11-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/88030 PR tree-optimization/88030
* tree-complex.c (need_eh_cleanup): New global. * tree-complex.c (need_eh_cleanup): New global.
(update_complex_assignment): Mark blocks that need EH update. (update_complex_assignment): Mark blocks that need EH update.
2018-11-15 Richard Biener <rguenther@suse.de>
PR tree-optimization/88031
* gcc.dg/pr88031.c: New testcase.
2018-11-15 Wilco Dijkstra <wdijkstr@arm.com> 2018-11-15 Wilco Dijkstra <wdijkstr@arm.com>
* gcc.target/aarch64/pr62178.c: Fix spaces. * gcc.target/aarch64/pr62178.c: Fix spaces.
......
/* { dg-do compile } */
/* { dg-options "-O3" } */
int a[512];
int b;
void d()
{
unsigned char c;
for (; b; b++) {
c = 1;
for (; c; c <<= 1) {
a[b] <<= 8;
if (b & c)
a[b] = 1;
}
}
}
...@@ -6491,14 +6491,24 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -6491,14 +6491,24 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
double_reduc = true; double_reduc = true;
} }
vect_reduction_type reduction_type
= STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info);
if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
&& ncopies > 1)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"multiple types in double reduction or condition "
"reduction.\n");
return false;
}
if (code == COND_EXPR) if (code == COND_EXPR)
{ {
/* Only call during the analysis stage, otherwise we'll lose /* Only call during the analysis stage, otherwise we'll lose
STMT_VINFO_TYPE. We'll pass ops[0] as reduc_op, it's only STMT_VINFO_TYPE. */
used as a flag during analysis. */
if (!vec_stmt && !vectorizable_condition (stmt_info, gsi, NULL, if (!vec_stmt && !vectorizable_condition (stmt_info, gsi, NULL,
ops[0], 0, NULL, true, NULL, cost_vec))
cost_vec))
{ {
if (dump_enabled_p ()) if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
...@@ -6598,8 +6608,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -6598,8 +6608,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
(and also the same tree-code) when generating the epilog code and (and also the same tree-code) when generating the epilog code and
when generating the code inside the loop. */ when generating the code inside the loop. */
vect_reduction_type reduction_type
= STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info);
if (orig_stmt_info if (orig_stmt_info
&& (reduction_type == TREE_CODE_REDUCTION && (reduction_type == TREE_CODE_REDUCTION
|| reduction_type == FOLD_LEFT_REDUCTION)) || reduction_type == FOLD_LEFT_REDUCTION))
...@@ -6689,16 +6697,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -6689,16 +6697,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
return false; return false;
} }
if ((double_reduc || reduction_type != TREE_CODE_REDUCTION)
&& ncopies > 1)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"multiple types in double reduction or condition "
"reduction.\n");
return false;
}
/* For SLP reductions, see if there is a neutral value we can use. */ /* For SLP reductions, see if there is a neutral value we can use. */
tree neutral_op = NULL_TREE; tree neutral_op = NULL_TREE;
if (slp_node) if (slp_node)
...@@ -6963,7 +6961,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -6963,7 +6961,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
{ {
gcc_assert (!slp_node); gcc_assert (!slp_node);
return vectorizable_condition (stmt_info, gsi, vec_stmt, return vectorizable_condition (stmt_info, gsi, vec_stmt,
NULL, reduc_index, NULL, NULL); true, NULL, NULL);
} }
/* Create the destination vector */ /* Create the destination vector */
...@@ -6995,9 +6993,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -6995,9 +6993,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
{ {
gcc_assert (!slp_node); gcc_assert (!slp_node);
vectorizable_condition (stmt_info, gsi, vec_stmt, vectorizable_condition (stmt_info, gsi, vec_stmt,
PHI_RESULT (phis[0]->stmt), true, NULL, NULL);
reduc_index, NULL, NULL);
/* Multiple types are not supported for condition. */
break; break;
} }
if (code == LSHIFT_EXPR if (code == LSHIFT_EXPR
......
...@@ -8675,17 +8675,14 @@ vect_is_simple_cond (tree cond, vec_info *vinfo, ...@@ -8675,17 +8675,14 @@ vect_is_simple_cond (tree cond, vec_info *vinfo,
stmt using VEC_COND_EXPR to replace it, put it in VEC_STMT, and insert it stmt using VEC_COND_EXPR to replace it, put it in VEC_STMT, and insert it
at GSI. at GSI.
When STMT_INFO is vectorized as a nested cycle, REDUC_DEF is the vector When STMT_INFO is vectorized as a nested cycle, for_reduction is true.
variable to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1,
and in else clause if it is 2).
Return true if STMT_INFO is vectorizable in this way. */ Return true if STMT_INFO is vectorizable in this way. */
bool bool
vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
stmt_vec_info *vec_stmt, tree reduc_def, stmt_vec_info *vec_stmt, bool for_reduction,
int reduc_index, slp_tree slp_node, slp_tree slp_node, stmt_vector_for_cost *cost_vec)
stmt_vector_for_cost *cost_vec)
{ {
vec_info *vinfo = stmt_info->vinfo; vec_info *vinfo = stmt_info->vinfo;
tree scalar_dest = NULL_TREE; tree scalar_dest = NULL_TREE;
...@@ -8714,7 +8711,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -8714,7 +8711,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
tree vec_cmp_type; tree vec_cmp_type;
bool masked = false; bool masked = false;
if (reduc_index && STMT_SLP_TYPE (stmt_info)) if (for_reduction && STMT_SLP_TYPE (stmt_info))
return false; return false;
vect_reduction_type reduction_type vect_reduction_type reduction_type
...@@ -8726,7 +8723,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -8726,7 +8723,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
&& !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle && !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
&& reduc_def)) && for_reduction))
return false; return false;
/* FORNOW: not yet supported. */ /* FORNOW: not yet supported. */
...@@ -8758,7 +8755,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -8758,7 +8755,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
ncopies = vect_get_num_copies (loop_vinfo, vectype); ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
if (reduc_index && ncopies > 1) if (for_reduction && ncopies > 1)
return false; /* FORNOW */ return false; /* FORNOW */
cond_expr = gimple_assign_rhs1 (stmt); cond_expr = gimple_assign_rhs1 (stmt);
...@@ -8928,22 +8925,12 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -8928,22 +8925,12 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
stmt_info, comp_vectype); stmt_info, comp_vectype);
vect_is_simple_use (cond_expr1, loop_vinfo, &dts[1]); vect_is_simple_use (cond_expr1, loop_vinfo, &dts[1]);
} }
if (reduc_index == 1) vec_then_clause = vect_get_vec_def_for_operand (then_clause,
vec_then_clause = reduc_def; stmt_info);
else vect_is_simple_use (then_clause, loop_vinfo, &dts[2]);
{ vec_else_clause = vect_get_vec_def_for_operand (else_clause,
vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt_info);
stmt_info); vect_is_simple_use (else_clause, loop_vinfo, &dts[3]);
vect_is_simple_use (then_clause, loop_vinfo, &dts[2]);
}
if (reduc_index == 2)
vec_else_clause = reduc_def;
else
{
vec_else_clause = vect_get_vec_def_for_operand (else_clause,
stmt_info);
vect_is_simple_use (else_clause, loop_vinfo, &dts[3]);
}
} }
} }
else else
...@@ -9023,7 +9010,6 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -9023,7 +9010,6 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
vect_finish_stmt_generation (stmt_info, new_stmt, gsi); vect_finish_stmt_generation (stmt_info, new_stmt, gsi);
vec_compare = vec_compare_name; vec_compare = vec_compare_name;
} }
gcc_assert (reduc_index == 2);
gcall *new_stmt = gimple_build_call_internal gcall *new_stmt = gimple_build_call_internal
(IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare, (IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare,
vec_then_clause); vec_then_clause);
...@@ -9085,7 +9071,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -9085,7 +9071,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
static bool static bool
vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
stmt_vec_info *vec_stmt, tree reduc_def, stmt_vec_info *vec_stmt,
slp_tree slp_node, stmt_vector_for_cost *cost_vec) slp_tree slp_node, stmt_vector_for_cost *cost_vec)
{ {
vec_info *vinfo = stmt_info->vinfo; vec_info *vinfo = stmt_info->vinfo;
...@@ -9123,9 +9109,7 @@ vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -9123,9 +9109,7 @@ vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
ncopies = vect_get_num_copies (loop_vinfo, vectype); ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1); gcc_assert (ncopies >= 1);
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
&& !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
&& reduc_def))
return false; return false;
if (STMT_VINFO_LIVE_P (stmt_info)) if (STMT_VINFO_LIVE_P (stmt_info))
...@@ -9556,9 +9540,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool *need_to_vectorize, ...@@ -9556,9 +9540,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool *need_to_vectorize,
node_instance, cost_vec) node_instance, cost_vec)
|| vectorizable_induction (stmt_info, NULL, NULL, node, cost_vec) || vectorizable_induction (stmt_info, NULL, NULL, node, cost_vec)
|| vectorizable_shift (stmt_info, NULL, NULL, node, cost_vec) || vectorizable_shift (stmt_info, NULL, NULL, node, cost_vec)
|| vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node, || vectorizable_condition (stmt_info, NULL, NULL, false, node,
cost_vec) cost_vec)
|| vectorizable_comparison (stmt_info, NULL, NULL, NULL, node, || vectorizable_comparison (stmt_info, NULL, NULL, node,
cost_vec)); cost_vec));
else else
{ {
...@@ -9575,9 +9559,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool *need_to_vectorize, ...@@ -9575,9 +9559,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool *need_to_vectorize,
|| vectorizable_load (stmt_info, NULL, NULL, node, node_instance, || vectorizable_load (stmt_info, NULL, NULL, node, node_instance,
cost_vec) cost_vec)
|| vectorizable_store (stmt_info, NULL, NULL, node, cost_vec) || vectorizable_store (stmt_info, NULL, NULL, node, cost_vec)
|| vectorizable_condition (stmt_info, NULL, NULL, NULL, 0, node, || vectorizable_condition (stmt_info, NULL, NULL, false, node,
cost_vec) cost_vec)
|| vectorizable_comparison (stmt_info, NULL, NULL, NULL, node, || vectorizable_comparison (stmt_info, NULL, NULL, node,
cost_vec)); cost_vec));
} }
...@@ -9680,13 +9664,13 @@ vect_transform_stmt (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi, ...@@ -9680,13 +9664,13 @@ vect_transform_stmt (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
break; break;
case condition_vec_info_type: case condition_vec_info_type:
done = vectorizable_condition (stmt_info, gsi, &vec_stmt, NULL, 0, done = vectorizable_condition (stmt_info, gsi, &vec_stmt, false,
slp_node, NULL); slp_node, NULL);
gcc_assert (done); gcc_assert (done);
break; break;
case comparison_vec_info_type: case comparison_vec_info_type:
done = vectorizable_comparison (stmt_info, gsi, &vec_stmt, NULL, done = vectorizable_comparison (stmt_info, gsi, &vec_stmt,
slp_node, NULL); slp_node, NULL);
gcc_assert (done); gcc_assert (done);
break; break;
......
...@@ -1481,7 +1481,7 @@ extern void vect_remove_stores (stmt_vec_info); ...@@ -1481,7 +1481,7 @@ extern void vect_remove_stores (stmt_vec_info);
extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree, extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree,
slp_instance, stmt_vector_for_cost *); slp_instance, stmt_vector_for_cost *);
extern bool vectorizable_condition (stmt_vec_info, gimple_stmt_iterator *, extern bool vectorizable_condition (stmt_vec_info, gimple_stmt_iterator *,
stmt_vec_info *, tree, int, slp_tree, stmt_vec_info *, bool, slp_tree,
stmt_vector_for_cost *); stmt_vector_for_cost *);
extern bool vectorizable_shift (stmt_vec_info, gimple_stmt_iterator *, extern bool vectorizable_shift (stmt_vec_info, gimple_stmt_iterator *,
stmt_vec_info *, slp_tree, stmt_vec_info *, slp_tree,
......
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