From 77eefb7122d544b9e22a7f40a92320742c23e74b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 2 Aug 2017 06:38:36 +0000 Subject: [PATCH] re PR tree-optimization/81633 (Incorrect floating point result with tree vectoriser) 2017-08-02 Richard Biener PR tree-optimization/81633 Revert 2015-08-17 Alan Hayward PR tree-optimization/71752 * tree-vect-slp.c (vect_get_slp_defs): Handle null operands. * gcc.dg/vect/pr81633.c: New testcase. From-SVN: r250811 --- gcc/ChangeLog | 9 +++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/vect/pr81633.c | 33 +++++++++++++++++ gcc/tree-vect-slp.c | 57 +++++++++++++---------------- 4 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr81633.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7bd462a972b..574745f7921 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-08-02 Richard Biener + + PR tree-optimization/81633 + Revert + 2015-08-17 Alan Hayward + + PR tree-optimization/71752 + * tree-vect-slp.c (vect_get_slp_defs): Handle null operands. + 2017-08-01 Daniel Santos * config/i386/i386.h (ix86_frame::outlined_save_offset): Remove field. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9b30f119a14..4e126f073f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-08-02 Richard Biener + + PR tree-optimization/81633 + * gcc.dg/vect/pr81633.c: New testcase. + 2017-08-01 H.J. Lu * gcc.dg/guality/pr25967-3.c: New test. diff --git a/gcc/testsuite/gcc.dg/vect/pr81633.c b/gcc/testsuite/gcc.dg/vect/pr81633.c new file mode 100644 index 00000000000..1ae15504e81 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr81633.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ + +static double identity[4][4] = {{1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}}; +static double expected[4][4] = {{1, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}; + +static void __attribute__((noinline,noclone)) +kernel(double A[4][4]) +{ + double tmp[4][4]; + for (int j = 0; j < 4; j++) + for (int k = 0; k < 4; k++) + tmp[j][k] = identity[j][0] * identity[j][k]; + for (int j = 0; j < 4; j++ ) + for (int k = 0; k < 4; k++) + A[j][k] = tmp[j][k]; +} + +int main(void) +{ + double A[4][4] = {{0.0}}; + kernel(A); + for ( int i = 0; i < 4; i++ ) + for ( int j = 0; j < 4; j++ ) + if (A[i][j] != expected[i][j]) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index 15d589d3452..032a9444a5a 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -3325,32 +3325,24 @@ 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 first_iteration = true; + bool vectorized_defs; 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 (). */ - for (unsigned int child_index = 0; - child_index < SLP_TREE_CHILDREN (slp_node).length (); child_index++) + 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) { child = SLP_TREE_CHILDREN (slp_node)[child_index]; @@ -3375,25 +3367,30 @@ vect_get_slp_defs (vec ops, slp_tree slp_node, statements. */ number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child); vectorized_defs = true; - break; + child_index++; } } + else + child_index++; } - 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; - } + 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; + } + } } /* Allocate memory for vectorized defs. */ @@ -3411,8 +3408,6 @@ vect_get_slp_defs (vec ops, slp_tree slp_node, number_of_vects); vec_oprnds->quick_push (vec_defs); - - first_iteration = false; } } -- 2.30.2