Commit bdc91a32 by Richard Biener Committed by Richard Biener

re PR tree-optimization/91750 (Induction vectorization introduces signed overflows)

2019-09-12  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/91750
	* tree-vect-loop.c (vectorizable_induction): Compute IV increments
	in the type of the evolution.

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

From-SVN: r275685
parent 52f6afe0
2019-09-12 Richard Biener <rguenther@suse.de>
PR tree-optimization/91750
* tree-vect-loop.c (vectorizable_induction): Compute IV increments
in the type of the evolution.
2019-09-12 Yuliang Wang <yuliang.wang@arm.com> 2019-09-12 Yuliang Wang <yuliang.wang@arm.com>
PR tree-optimization/89386 PR tree-optimization/89386
......
2019-09-12 Richard Biener <rguenther@suse.de>
PR tree-optimization/91750
* gcc.dg/vect/pr91750.c: New testcase.
2019-09-11 Sandra Loosemore <sandra@codesourcery.com> 2019-09-11 Sandra Loosemore <sandra@codesourcery.com>
PR testsuite/83889 PR testsuite/83889
......
/* { dg-do compile } */
/* { dg-require-effective-target vect_int } */
int val[1024];
void
foo (int n)
{
int i;
for (int j = 0, i = n; j < 1024; ++j, i=(unsigned)i+1)
val[j] = i;
}
/* Make sure the induction IV uses an unsigned increment. */
/* { dg-final { scan-tree-dump "vector\\\(\[0-9\]*\\\) unsigned int" "vect" } } */
/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
...@@ -7605,6 +7605,7 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7605,6 +7605,7 @@ vectorizable_induction (stmt_vec_info stmt_info,
step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_info); step_expr = STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_info);
gcc_assert (step_expr != NULL_TREE); gcc_assert (step_expr != NULL_TREE);
tree step_vectype = get_same_sized_vectype (TREE_TYPE (step_expr), vectype);
pe = loop_preheader_edge (iv_loop); pe = loop_preheader_edge (iv_loop);
init_expr = PHI_ARG_DEF_FROM_EDGE (phi, init_expr = PHI_ARG_DEF_FROM_EDGE (phi,
...@@ -7613,8 +7614,8 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7613,8 +7614,8 @@ vectorizable_induction (stmt_vec_info stmt_info,
stmts = NULL; stmts = NULL;
if (!nested_in_vect_loop) if (!nested_in_vect_loop)
{ {
/* Convert the initial value to the desired type. */ /* Convert the initial value to the IV update type. */
tree new_type = TREE_TYPE (vectype); tree new_type = TREE_TYPE (step_expr);
init_expr = gimple_convert (&stmts, new_type, init_expr); init_expr = gimple_convert (&stmts, new_type, init_expr);
/* If we are using the loop mask to "peel" for alignment then we need /* If we are using the loop mask to "peel" for alignment then we need
...@@ -7634,9 +7635,6 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7634,9 +7635,6 @@ vectorizable_induction (stmt_vec_info stmt_info,
} }
} }
/* Convert the step to the desired type. */
step_expr = gimple_convert (&stmts, TREE_TYPE (vectype), step_expr);
if (stmts) if (stmts)
{ {
new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
...@@ -7669,8 +7667,8 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7669,8 +7667,8 @@ vectorizable_induction (stmt_vec_info stmt_info,
if (! CONSTANT_CLASS_P (new_name)) if (! CONSTANT_CLASS_P (new_name))
new_name = vect_init_vector (stmt_info, new_name, new_name = vect_init_vector (stmt_info, new_name,
TREE_TYPE (step_expr), NULL); TREE_TYPE (step_expr), NULL);
new_vec = build_vector_from_val (vectype, new_name); new_vec = build_vector_from_val (step_vectype, new_name);
vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL);
/* Now generate the IVs. */ /* Now generate the IVs. */
unsigned group_size = SLP_TREE_SCALAR_STMTS (slp_node).length (); unsigned group_size = SLP_TREE_SCALAR_STMTS (slp_node).length ();
...@@ -7683,7 +7681,7 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7683,7 +7681,7 @@ vectorizable_induction (stmt_vec_info stmt_info,
unsigned ivn; unsigned ivn;
for (ivn = 0; ivn < nivs; ++ivn) for (ivn = 0; ivn < nivs; ++ivn)
{ {
tree_vector_builder elts (vectype, const_nunits, 1); tree_vector_builder elts (step_vectype, const_nunits, 1);
stmts = NULL; stmts = NULL;
for (unsigned eltn = 0; eltn < const_nunits; ++eltn) for (unsigned eltn = 0; eltn < const_nunits; ++eltn)
{ {
...@@ -7694,6 +7692,7 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7694,6 +7692,7 @@ vectorizable_induction (stmt_vec_info stmt_info,
elts.quick_push (elt); elts.quick_push (elt);
} }
vec_init = gimple_build_vector (&stmts, &elts); vec_init = gimple_build_vector (&stmts, &elts);
vec_init = gimple_convert (&stmts, vectype, vec_init);
if (stmts) if (stmts)
{ {
new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts); new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
...@@ -7708,10 +7707,13 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7708,10 +7707,13 @@ vectorizable_induction (stmt_vec_info stmt_info,
induc_def = PHI_RESULT (induction_phi); induc_def = PHI_RESULT (induction_phi);
/* Create the iv update inside the loop */ /* Create the iv update inside the loop */
vec_def = make_ssa_name (vec_dest); gimple_seq stmts = NULL;
new_stmt = gimple_build_assign (vec_def, PLUS_EXPR, induc_def, vec_step); vec_def = gimple_convert (&stmts, step_vectype, induc_def);
gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); vec_def = gimple_build (&stmts,
loop_vinfo->add_stmt (new_stmt); PLUS_EXPR, step_vectype, vec_def, vec_step);
vec_def = gimple_convert (&stmts, vectype, vec_def);
loop_vinfo->add_stmt (SSA_NAME_DEF_STMT (vec_def));
gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT);
/* Set the arguments of the phi node: */ /* Set the arguments of the phi node: */
add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION); add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION);
...@@ -7739,8 +7741,8 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7739,8 +7741,8 @@ vectorizable_induction (stmt_vec_info stmt_info,
if (! CONSTANT_CLASS_P (new_name)) if (! CONSTANT_CLASS_P (new_name))
new_name = vect_init_vector (stmt_info, new_name, new_name = vect_init_vector (stmt_info, new_name,
TREE_TYPE (step_expr), NULL); TREE_TYPE (step_expr), NULL);
new_vec = build_vector_from_val (vectype, new_name); new_vec = build_vector_from_val (step_vectype, new_name);
vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL);
for (; ivn < nvects; ++ivn) for (; ivn < nvects; ++ivn)
{ {
gimple *iv = SLP_TREE_VEC_STMTS (slp_node)[ivn - nivs]->stmt; gimple *iv = SLP_TREE_VEC_STMTS (slp_node)[ivn - nivs]->stmt;
...@@ -7749,18 +7751,20 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7749,18 +7751,20 @@ vectorizable_induction (stmt_vec_info stmt_info,
def = gimple_phi_result (iv); def = gimple_phi_result (iv);
else else
def = gimple_assign_lhs (iv); def = gimple_assign_lhs (iv);
new_stmt = gimple_build_assign (make_ssa_name (vectype), gimple_seq stmts = NULL;
PLUS_EXPR, def = gimple_convert (&stmts, step_vectype, def);
def, vec_step); def = gimple_build (&stmts,
PLUS_EXPR, step_vectype, def, vec_step);
def = gimple_convert (&stmts, vectype, def);
if (gimple_code (iv) == GIMPLE_PHI) if (gimple_code (iv) == GIMPLE_PHI)
gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT);
else else
{ {
gimple_stmt_iterator tgsi = gsi_for_stmt (iv); gimple_stmt_iterator tgsi = gsi_for_stmt (iv);
gsi_insert_after (&tgsi, new_stmt, GSI_CONTINUE_LINKING); gsi_insert_seq_after (&tgsi, stmts, GSI_CONTINUE_LINKING);
} }
SLP_TREE_VEC_STMTS (slp_node).quick_push SLP_TREE_VEC_STMTS (slp_node).quick_push
(loop_vinfo->add_stmt (new_stmt)); (loop_vinfo->add_stmt (SSA_NAME_DEF_STMT (def)));
} }
} }
...@@ -7796,12 +7800,12 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7796,12 +7800,12 @@ vectorizable_induction (stmt_vec_info stmt_info,
/* iv_loop is the loop to be vectorized. Create: /* iv_loop is the loop to be vectorized. Create:
vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */ vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */
stmts = NULL; stmts = NULL;
new_name = gimple_convert (&stmts, TREE_TYPE (vectype), init_expr); new_name = gimple_convert (&stmts, TREE_TYPE (step_expr), init_expr);
unsigned HOST_WIDE_INT const_nunits; unsigned HOST_WIDE_INT const_nunits;
if (nunits.is_constant (&const_nunits)) if (nunits.is_constant (&const_nunits))
{ {
tree_vector_builder elts (vectype, const_nunits, 1); tree_vector_builder elts (step_vectype, const_nunits, 1);
elts.quick_push (new_name); elts.quick_push (new_name);
for (i = 1; i < const_nunits; i++) for (i = 1; i < const_nunits; i++)
{ {
...@@ -7816,7 +7820,7 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7816,7 +7820,7 @@ vectorizable_induction (stmt_vec_info stmt_info,
} }
else if (INTEGRAL_TYPE_P (TREE_TYPE (step_expr))) else if (INTEGRAL_TYPE_P (TREE_TYPE (step_expr)))
/* Build the initial value directly from a VEC_SERIES_EXPR. */ /* Build the initial value directly from a VEC_SERIES_EXPR. */
vec_init = gimple_build (&stmts, VEC_SERIES_EXPR, vectype, vec_init = gimple_build (&stmts, VEC_SERIES_EXPR, step_vectype,
new_name, step_expr); new_name, step_expr);
else else
{ {
...@@ -7825,17 +7829,18 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7825,17 +7829,18 @@ vectorizable_induction (stmt_vec_info stmt_info,
+ (vectype) [0, 1, 2, ...] * [step, step, step, ...]. */ + (vectype) [0, 1, 2, ...] * [step, step, step, ...]. */
gcc_assert (SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr))); gcc_assert (SCALAR_FLOAT_TYPE_P (TREE_TYPE (step_expr)));
gcc_assert (flag_associative_math); gcc_assert (flag_associative_math);
tree index = build_index_vector (vectype, 0, 1); tree index = build_index_vector (step_vectype, 0, 1);
tree base_vec = gimple_build_vector_from_val (&stmts, vectype, tree base_vec = gimple_build_vector_from_val (&stmts, step_vectype,
new_name); new_name);
tree step_vec = gimple_build_vector_from_val (&stmts, vectype, tree step_vec = gimple_build_vector_from_val (&stmts, step_vectype,
step_expr); step_expr);
vec_init = gimple_build (&stmts, FLOAT_EXPR, vectype, index); vec_init = gimple_build (&stmts, FLOAT_EXPR, step_vectype, index);
vec_init = gimple_build (&stmts, MULT_EXPR, vectype, vec_init = gimple_build (&stmts, MULT_EXPR, step_vectype,
vec_init, step_vec); vec_init, step_vec);
vec_init = gimple_build (&stmts, PLUS_EXPR, vectype, vec_init = gimple_build (&stmts, PLUS_EXPR, step_vectype,
vec_init, base_vec); vec_init, base_vec);
} }
vec_init = gimple_convert (&stmts, vectype, vec_init);
if (stmts) if (stmts)
{ {
...@@ -7874,8 +7879,8 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7874,8 +7879,8 @@ vectorizable_induction (stmt_vec_info stmt_info,
t = unshare_expr (new_name); t = unshare_expr (new_name);
gcc_assert (CONSTANT_CLASS_P (new_name) gcc_assert (CONSTANT_CLASS_P (new_name)
|| TREE_CODE (new_name) == SSA_NAME); || TREE_CODE (new_name) == SSA_NAME);
new_vec = build_vector_from_val (vectype, t); new_vec = build_vector_from_val (step_vectype, t);
vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL);
/* Create the following def-use cycle: /* Create the following def-use cycle:
...@@ -7896,9 +7901,12 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7896,9 +7901,12 @@ vectorizable_induction (stmt_vec_info stmt_info,
induc_def = PHI_RESULT (induction_phi); induc_def = PHI_RESULT (induction_phi);
/* Create the iv update inside the loop */ /* Create the iv update inside the loop */
vec_def = make_ssa_name (vec_dest); stmts = NULL;
new_stmt = gimple_build_assign (vec_def, PLUS_EXPR, induc_def, vec_step); vec_def = gimple_convert (&stmts, step_vectype, induc_def);
gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); vec_def = gimple_build (&stmts, PLUS_EXPR, step_vectype, vec_def, vec_step);
vec_def = gimple_convert (&stmts, vectype, vec_def);
gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT);
new_stmt = SSA_NAME_DEF_STMT (vec_def);
stmt_vec_info new_stmt_info = loop_vinfo->add_stmt (new_stmt); stmt_vec_info new_stmt_info = loop_vinfo->add_stmt (new_stmt);
/* Set the arguments of the phi node: */ /* Set the arguments of the phi node: */
...@@ -7940,20 +7948,22 @@ vectorizable_induction (stmt_vec_info stmt_info, ...@@ -7940,20 +7948,22 @@ vectorizable_induction (stmt_vec_info stmt_info,
t = unshare_expr (new_name); t = unshare_expr (new_name);
gcc_assert (CONSTANT_CLASS_P (new_name) gcc_assert (CONSTANT_CLASS_P (new_name)
|| TREE_CODE (new_name) == SSA_NAME); || TREE_CODE (new_name) == SSA_NAME);
new_vec = build_vector_from_val (vectype, t); new_vec = build_vector_from_val (step_vectype, t);
vec_step = vect_init_vector (stmt_info, new_vec, vectype, NULL); vec_step = vect_init_vector (stmt_info, new_vec, step_vectype, NULL);
vec_def = induc_def; vec_def = induc_def;
prev_stmt_vinfo = induction_phi_info; prev_stmt_vinfo = induction_phi_info;
for (i = 1; i < ncopies; i++) for (i = 1; i < ncopies; i++)
{ {
/* vec_i = vec_prev + vec_step */ /* vec_i = vec_prev + vec_step */
new_stmt = gimple_build_assign (vec_dest, PLUS_EXPR, gimple_seq stmts = NULL;
vec_def, vec_step); vec_def = gimple_convert (&stmts, step_vectype, vec_def);
vec_def = make_ssa_name (vec_dest, new_stmt); vec_def = gimple_build (&stmts,
gimple_assign_set_lhs (new_stmt, vec_def); PLUS_EXPR, step_vectype, vec_def, vec_step);
vec_def = gimple_convert (&stmts, vectype, vec_def);
gsi_insert_before (&si, new_stmt, GSI_SAME_STMT); gsi_insert_seq_before (&si, stmts, GSI_SAME_STMT);
new_stmt = SSA_NAME_DEF_STMT (vec_def);
new_stmt_info = loop_vinfo->add_stmt (new_stmt); new_stmt_info = loop_vinfo->add_stmt (new_stmt);
STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt_info; STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt_info;
prev_stmt_vinfo = new_stmt_info; prev_stmt_vinfo = new_stmt_info;
......
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