]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
2018-11-13 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Nov 2018 13:51:34 +0000 (13:51 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Nov 2018 13:51:34 +0000 (13:51 +0000)
PR tree-optimization/87962
* tree-vect-loop.c (vect_is_simple_reduction): More reliably
detect outer reduction for disqualifying in-loop uses.

* gcc.dg/pr87962.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266071 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr87962.c [new file with mode: 0644]
gcc/tree-vect-loop.c

index 19ccd9cbf1d019948f542a41feac979e9372150d..95ea4cdc6852b981ba464845164bdb64428424d0 100644 (file)
@@ -1,3 +1,9 @@
+2018-11-13  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87962
+       * tree-vect-loop.c (vect_is_simple_reduction): More reliably
+       detect outer reduction for disqualifying in-loop uses.
+
 2018-11-13  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/87967
index 41ffd8b310087464f42be78b34a38027cf88835f..bc4530845fc0f77afdcdf5c5eb20b3607b7f92ad 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-13  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/87962
+       * gcc.dg/pr87962.c: New testcase.
+
 2018-11-13  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/87967
diff --git a/gcc/testsuite/gcc.dg/pr87962.c b/gcc/testsuite/gcc.dg/pr87962.c
new file mode 100644 (file)
index 0000000..6a551d3
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-additional-options "-march=bdver2" { target { x86_64-*-* i?86-*-* } } } */
+
+int a, b;
+
+int c()
+{
+  long d, e;
+  while (a) {
+      a++;
+      b = 0;
+      for (; b++ - 2; d = d >> 1)
+       e += d;
+  }
+  return e;
+}
index c4886ec76e66880f0efcb44956ad25248aecfdc7..a6f0b823ddafeef3bbbb5ec872f4054103b90b09 100644 (file)
@@ -2807,11 +2807,11 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
   gphi *phi = as_a <gphi *> (phi_info->stmt);
   struct loop *loop = (gimple_bb (phi))->loop_father;
   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
+  bool nested_in_vect_loop = flow_loop_nested_p (vect_loop, loop);
   gimple *phi_use_stmt = NULL;
   enum tree_code orig_code, code;
   tree op1, op2, op3 = NULL_TREE, op4 = NULL_TREE;
   tree type;
-  int nloop_uses;
   tree name;
   imm_use_iterator imm_iter;
   use_operand_p use_p;
@@ -2827,7 +2827,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
      can be constant.  See PR60382.  */
   if (has_zero_uses (phi_name))
     return NULL;
-  nloop_uses = 0;
+  unsigned nphi_def_loop_uses = 0;
   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, phi_name)
     {
       gimple *use_stmt = USE_STMT (use_p);
@@ -2843,20 +2843,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
           return NULL;
         }
 
-      /* For inner loop reductions in nested vectorization there are no
-         constraints on the number of uses in the inner loop.  */
-      if (loop == vect_loop->inner)
-       continue;
-
-      nloop_uses++;
-      if (nloop_uses > 1)
-        {
-          if (dump_enabled_p ())
-           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                            "reduction value used in loop.\n");
-          return NULL;
-        }
-
+      nphi_def_loop_uses++;
       phi_use_stmt = use_stmt;
     }
 
@@ -2894,26 +2881,32 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
       return NULL;
     }
 
-  nloop_uses = 0;
+  unsigned nlatch_def_loop_uses = 0;
   auto_vec<gphi *, 3> lcphis;
+  bool inner_loop_of_double_reduc = false;
   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
     {
       gimple *use_stmt = USE_STMT (use_p);
       if (is_gimple_debug (use_stmt))
        continue;
       if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
-       nloop_uses++;
+       nlatch_def_loop_uses++;
       else
-       /* We can have more than one loop-closed PHI.  */
-       lcphis.safe_push (as_a <gphi *> (use_stmt));
+       {
+         /* We can have more than one loop-closed PHI.  */
+         lcphis.safe_push (as_a <gphi *> (use_stmt));
+         if (nested_in_vect_loop
+             && (STMT_VINFO_DEF_TYPE (loop_info->lookup_stmt (use_stmt))
+                 == vect_double_reduction_def))
+           inner_loop_of_double_reduc = true;
+       }
     }
 
   /* If this isn't a nested cycle or if the nested cycle reduction value
      is used ouside of the inner loop we cannot handle uses of the reduction
      value.  */
-  bool nested_in_vect_loop = flow_loop_nested_p (vect_loop, loop);
-  if ((!nested_in_vect_loop || !lcphis.is_empty ())
-      && nloop_uses > 1)
+  if ((!nested_in_vect_loop || inner_loop_of_double_reduc)
+      && (nlatch_def_loop_uses > 1 || nphi_def_loop_uses > 1))
     {
       if (dump_enabled_p ())
        dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,