The following fixes a missing check on commutativity / associativity in reduction detection.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2016-01-27 Richard Biener <rguent...@suse.de> PR tree-optimization/69166 * tree-vect-loop.c (vect_is_simple_reduction): Always check reduction code for commutativity / associativity. * gcc.dg/torture/pr69166.c: New testcase. Index: gcc/tree-vect-loop.c =================================================================== *** gcc/tree-vect-loop.c (revision 232867) --- gcc/tree-vect-loop.c (working copy) *************** vect_is_simple_reduction (loop_vec_info *** 2750,2766 **** && SSA_NAME_DEF_STMT (op1) == phi) code = PLUS_EXPR; ! if (check_reduction) { ! if (code == COND_EXPR) *v_reduc_type = COND_REDUCTION; ! else if (!commutative_tree_code (code) || !associative_tree_code (code)) ! { ! if (dump_enabled_p ()) ! report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt, ! "reduction: not commutative/associative: "); ! return NULL; ! } } if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS) --- 2741,2757 ---- && SSA_NAME_DEF_STMT (op1) == phi) code = PLUS_EXPR; ! if (code == COND_EXPR) { ! if (check_reduction) *v_reduc_type = COND_REDUCTION; ! } ! else if (!commutative_tree_code (code) || !associative_tree_code (code)) ! { ! if (dump_enabled_p ()) ! report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt, ! "reduction: not commutative/associative: "); ! return NULL; } if (get_gimple_rhs_class (code) != GIMPLE_BINARY_RHS) *************** vect_is_simple_reduction (loop_vec_info *** 2856,2866 **** and therefore vectorizing reductions in the inner-loop during outer-loop vectorization is safe. */ ! if (*v_reduc_type != COND_REDUCTION) { /* CHECKME: check for !flag_finite_math_only too? */ ! if (SCALAR_FLOAT_TYPE_P (type) && !flag_associative_math ! && check_reduction) { /* Changing the order of operations changes the semantics. */ if (dump_enabled_p ()) --- 2847,2857 ---- and therefore vectorizing reductions in the inner-loop during outer-loop vectorization is safe. */ ! if (*v_reduc_type != COND_REDUCTION ! && check_reduction) { /* CHECKME: check for !flag_finite_math_only too? */ ! if (SCALAR_FLOAT_TYPE_P (type) && !flag_associative_math) { /* Changing the order of operations changes the semantics. */ if (dump_enabled_p ()) *************** vect_is_simple_reduction (loop_vec_info *** 2868,2874 **** "reduction: unsafe fp math optimization: "); return NULL; } ! else if (INTEGRAL_TYPE_P (type) && check_reduction) { if (!operation_no_trapping_overflow (type, code)) { --- 2859,2865 ---- "reduction: unsafe fp math optimization: "); return NULL; } ! else if (INTEGRAL_TYPE_P (type)) { if (!operation_no_trapping_overflow (type, code)) { *************** vect_is_simple_reduction (loop_vec_info *** 2891,2897 **** return NULL; } } ! else if (SAT_FIXED_POINT_TYPE_P (type) && check_reduction) { /* Changing the order of operations changes the semantics. */ if (dump_enabled_p ()) --- 2882,2888 ---- return NULL; } } ! else if (SAT_FIXED_POINT_TYPE_P (type)) { /* Changing the order of operations changes the semantics. */ if (dump_enabled_p ()) Index: gcc/testsuite/gcc.dg/torture/pr69166.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr69166.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr69166.c (working copy) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + + void fn2(double *e, double a) + { + int b = 0; + for (; b < 256; b++) + { + int c = 0; + double x = e[b]; + for (; c < 256; ++c) + x /= a; + e[b] = x; + } + }