From dd116fe4b7b2306ea5f56bf8070d7ac36fdfaa0e Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Wed, 17 Aug 2016 15:31:44 +0000 Subject: 2015-08-17 Alan Hayward PR tree-optimization/71752 * tree-vect-loop.c (vectorizable_reduction): Keep SLP operand ordering. * tree-vect-slp.c (vect_get_slp_defs): Handle null operands. PR tree-optimization/71752 * gcc.dg/vect/pr71752.c: New git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@239542 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/vect/pr71752.c | 19 +++++++++++++ gcc/tree-vect-loop.c | 35 ++++++++++++++--------- gcc/tree-vect-slp.c | 57 ++++++++++++++++++++----------------- 5 files changed, 82 insertions(+), 40 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr71752.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c27eae13d7..6f6314671aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-08-17 Alan Hayward + + PR tree-optimization/71752 + * tree-vect-loop.c (vectorizable_reduction): Keep SLP operand ordering. + * tree-vect-slp.c (vect_get_slp_defs): Handle null operands. + 2016-08-17 Jakub Jelinek * gimple-fold.c (gimple_fold_call): Use gimple_call_noreturn_p diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 98d030dc419..2c6ed263dca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-08-17 Alan Hayward + + PR tree-optimization/71752 + * gcc.dg/vect/pr71752.c: New + 2016-08-17 Uros Bizjak * gfortran.dg/dec_init_2.f90: Use dg-add-options ieee. diff --git a/gcc/testsuite/gcc.dg/vect/pr71752.c b/gcc/testsuite/gcc.dg/vect/pr71752.c new file mode 100644 index 00000000000..8d26754b4fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr71752.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +unsigned int q4, yg; + +unsigned int +w6 (unsigned int z5, unsigned int jv) +{ + unsigned int *f2 = &jv; + + while (*f2 < 21) + { + q4 -= jv; + z5 -= jv; + f2 = &yg; + ++(*f2); + } + return z5; +} + diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 4957b66c432..c9ba5810e70 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -5444,7 +5444,7 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, auto_vec vect_defs; auto_vec phis; int vec_num; - tree def0, def1, tem, op0, op1 = NULL_TREE; + tree def0, def1, tem, op1 = NULL_TREE; bool first_p = true; tree cr_index_scalar_type = NULL_TREE, cr_index_vector_type = NULL_TREE; tree cond_reduc_val = NULL_TREE, const_cond_cmp = NULL_TREE; @@ -6090,29 +6090,36 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi, /* Handle uses. */ if (j == 0) { - op0 = ops[!reduc_index]; - if (op_type == ternary_op) - { - if (reduc_index == 0) - op1 = ops[2]; - else - op1 = ops[1]; - } + if (slp_node) + { + /* Get vec defs for all the operands except the reduction index, + ensuring the ordering of the ops in the vector is kept. */ + auto_vec slp_ops; + auto_vec, 3> vec_defs; - if (slp_node) - vect_get_vec_defs (op0, op1, stmt, &vec_oprnds0, &vec_oprnds1, - slp_node, -1); + slp_ops.quick_push ((reduc_index == 0) ? NULL : ops[0]); + slp_ops.quick_push ((reduc_index == 1) ? NULL : ops[1]); + if (op_type == ternary_op) + slp_ops.quick_push ((reduc_index == 2) ? NULL : ops[2]); + + vect_get_slp_defs (slp_ops, slp_node, &vec_defs, -1); + + vec_oprnds0.safe_splice (vec_defs[(reduc_index == 0) ? 1 : 0]); + if (op_type == ternary_op) + vec_oprnds1.safe_splice (vec_defs[(reduc_index == 2) ? 1 : 2]); + } else - { + { loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index], stmt); vec_oprnds0.quick_push (loop_vec_def0); if (op_type == ternary_op) { + op1 = (reduc_index == 0) ? ops[2] : ops[1]; loop_vec_def1 = vect_get_vec_def_for_operand (op1, stmt); vec_oprnds1.quick_push (loop_vec_def1); } - } + } } else { diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index fb325d54f10..5a611e42556 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -3194,24 +3194,32 @@ vect_get_slp_defs (vec ops, slp_tree slp_node, { gimple *first_stmt; int number_of_vects = 0, i; - unsigned int child_index = 0; HOST_WIDE_INT lhs_size_unit, rhs_size_unit; slp_tree child = NULL; vec vec_defs; tree oprnd; - bool vectorized_defs; + bool first_iteration = true; first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0]; FOR_EACH_VEC_ELT (ops, i, oprnd) { + bool vectorized_defs = false; + + if (oprnd == NULL) + { + vec_defs = vNULL; + vec_defs.create (0); + vec_oprnds->quick_push (vec_defs); + continue; + } + /* For each operand we check if it has vectorized definitions in a child node or we need to create them (for invariants and constants). We check if the LHS of the first stmt of the next child matches OPRND. If it does, we found the correct child. Otherwise, we call - vect_get_constant_vectors (), and not advance CHILD_INDEX in order - to check this child node for the next operand. */ - vectorized_defs = false; - if (SLP_TREE_CHILDREN (slp_node).length () > child_index) + vect_get_constant_vectors (). */ + for (unsigned int child_index = 0; + child_index < SLP_TREE_CHILDREN (slp_node).length (); child_index++) { child = SLP_TREE_CHILDREN (slp_node)[child_index]; @@ -3231,30 +3239,25 @@ vect_get_slp_defs (vec ops, slp_tree slp_node, statements. */ number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child); vectorized_defs = true; - child_index++; + break; } } - else - child_index++; } - if (!vectorized_defs) - { - if (i == 0) - { - number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); - /* Number of vector stmts was calculated according to LHS in - vect_schedule_slp_instance (), fix it by replacing LHS with - RHS, if necessary. See vect_get_smallest_scalar_type () for - details. */ - vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit, - &rhs_size_unit); - if (rhs_size_unit != lhs_size_unit) - { - number_of_vects *= rhs_size_unit; - number_of_vects /= lhs_size_unit; - } - } + if (!vectorized_defs && first_iteration) + { + number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); + /* Number of vector stmts was calculated according to LHS in + vect_schedule_slp_instance (), fix it by replacing LHS with + RHS, if necessary. See vect_get_smallest_scalar_type () for + details. */ + vect_get_smallest_scalar_type (first_stmt, &lhs_size_unit, + &rhs_size_unit); + if (rhs_size_unit != lhs_size_unit) + { + number_of_vects *= rhs_size_unit; + number_of_vects /= lhs_size_unit; + } } /* Allocate memory for vectorized defs. */ @@ -3276,6 +3279,8 @@ vect_get_slp_defs (vec ops, slp_tree slp_node, /* For reductions, we only need initial values. */ if (reduc_index != -1) return; + + first_iteration = false; } } -- cgit v1.2.3