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;
+     }
+ }

Reply via email to