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
This commit is contained in:
Richard Biener 2018-11-15 13:42:13 +00:00 committed by Richard Biener
parent 3f5a0fdefb
commit 22692f3ce9
6 changed files with 71 additions and 57 deletions

View File

@ -1,3 +1,15 @@
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

View File

@ -1,3 +1,8 @@
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>
* gcc.target/aarch64/pr62178.c: Fix spaces.

View File

@ -0,0 +1,17 @@
/* { 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;
}
}
}

View File

@ -6491,14 +6491,24 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
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)
{
/* Only call during the analysis stage, otherwise we'll lose
STMT_VINFO_TYPE. We'll pass ops[0] as reduc_op, it's only
used as a flag during analysis. */
STMT_VINFO_TYPE. */
if (!vec_stmt && !vectorizable_condition (stmt_info, gsi, NULL,
ops[0], 0, NULL,
cost_vec))
true, NULL, cost_vec))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
@ -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
when generating the code inside the loop. */
vect_reduction_type reduction_type
= STMT_VINFO_VEC_REDUCTION_TYPE (stmt_info);
if (orig_stmt_info
&& (reduction_type == TREE_CODE_REDUCTION
|| reduction_type == FOLD_LEFT_REDUCTION))
@ -6689,16 +6697,6 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
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. */
tree neutral_op = NULL_TREE;
if (slp_node)
@ -6963,7 +6961,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
{
gcc_assert (!slp_node);
return vectorizable_condition (stmt_info, gsi, vec_stmt,
NULL, reduc_index, NULL, NULL);
true, NULL, NULL);
}
/* Create the destination vector */
@ -6995,9 +6993,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
{
gcc_assert (!slp_node);
vectorizable_condition (stmt_info, gsi, vec_stmt,
PHI_RESULT (phis[0]->stmt),
reduc_index, NULL, NULL);
/* Multiple types are not supported for condition. */
true, NULL, NULL);
break;
}
if (code == LSHIFT_EXPR

View File

@ -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
at GSI.
When STMT_INFO is vectorized as a nested cycle, REDUC_DEF is the vector
variable to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1,
and in else clause if it is 2).
When STMT_INFO is vectorized as a nested cycle, for_reduction is true.
Return true if STMT_INFO is vectorizable in this way. */
bool
vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
stmt_vec_info *vec_stmt, tree reduc_def,
int reduc_index, slp_tree slp_node,
stmt_vector_for_cost *cost_vec)
stmt_vec_info *vec_stmt, bool for_reduction,
slp_tree slp_node, stmt_vector_for_cost *cost_vec)
{
vec_info *vinfo = stmt_info->vinfo;
tree scalar_dest = NULL_TREE;
@ -8714,7 +8711,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
tree vec_cmp_type;
bool masked = false;
if (reduc_index && STMT_SLP_TYPE (stmt_info))
if (for_reduction && STMT_SLP_TYPE (stmt_info))
return false;
vect_reduction_type reduction_type
@ -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
&& !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
&& reduc_def))
&& for_reduction))
return false;
/* FORNOW: not yet supported. */
@ -8758,7 +8755,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
if (reduc_index && ncopies > 1)
if (for_reduction && ncopies > 1)
return false; /* FORNOW */
cond_expr = gimple_assign_rhs1 (stmt);
@ -8928,22 +8925,12 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
stmt_info, comp_vectype);
vect_is_simple_use (cond_expr1, loop_vinfo, &dts[1]);
}
if (reduc_index == 1)
vec_then_clause = reduc_def;
else
{
vec_then_clause = vect_get_vec_def_for_operand (then_clause,
stmt_info);
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]);
}
vec_then_clause = vect_get_vec_def_for_operand (then_clause,
stmt_info);
vect_is_simple_use (then_clause, loop_vinfo, &dts[2]);
vec_else_clause = vect_get_vec_def_for_operand (else_clause,
stmt_info);
vect_is_simple_use (else_clause, loop_vinfo, &dts[3]);
}
}
else
@ -9023,7 +9010,6 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
vect_finish_stmt_generation (stmt_info, new_stmt, gsi);
vec_compare = vec_compare_name;
}
gcc_assert (reduc_index == 2);
gcall *new_stmt = gimple_build_call_internal
(IFN_FOLD_EXTRACT_LAST, 3, else_clause, vec_compare,
vec_then_clause);
@ -9085,7 +9071,7 @@ vectorizable_condition (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
static bool
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)
{
vec_info *vinfo = stmt_info->vinfo;
@ -9123,9 +9109,7 @@ vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
ncopies = vect_get_num_copies (loop_vinfo, vectype);
gcc_assert (ncopies >= 1);
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
&& !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
&& reduc_def))
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
return false;
if (STMT_VINFO_LIVE_P (stmt_info))
@ -9556,9 +9540,9 @@ vect_analyze_stmt (stmt_vec_info stmt_info, bool *need_to_vectorize,
node_instance, cost_vec)
|| vectorizable_induction (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)
|| vectorizable_comparison (stmt_info, NULL, NULL, NULL, node,
|| vectorizable_comparison (stmt_info, NULL, NULL, node,
cost_vec));
else
{
@ -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,
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)
|| vectorizable_comparison (stmt_info, NULL, NULL, NULL, node,
|| vectorizable_comparison (stmt_info, NULL, NULL, node,
cost_vec));
}
@ -9680,13 +9664,13 @@ vect_transform_stmt (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
break;
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);
gcc_assert (done);
break;
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);
gcc_assert (done);
break;

View File

@ -1481,7 +1481,7 @@ extern void vect_remove_stores (stmt_vec_info);
extern opt_result vect_analyze_stmt (stmt_vec_info, bool *, slp_tree,
slp_instance, stmt_vector_for_cost *);
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 *);
extern bool vectorizable_shift (stmt_vec_info, gimple_stmt_iterator *,
stmt_vec_info *, slp_tree,