The following fixes the issue that if the reduction stmt (the stmt
defining the backedge value of a loop PHI) is not in the loop
then this isn't a reduction thus we shouldn't continue analysis.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2017-07-25  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/81510
        * tree-vect-loop.c (vect_is_simple_reduction): When the
        reduction stmt is not inside the loop bail out.

        * gcc.dg/torture/pr81510.c: New testcase.
        * gcc.dg/torture/pr81510-2.c: Likewise.

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c        (revision 250493)
+++ gcc/tree-vect-loop.c        (working copy)
@@ -2813,27 +2813,29 @@ vect_is_simple_reduction (loop_vec_info
       return NULL;
     }
 
+  if (! flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
+    return NULL;
+
   nloop_uses = 0;
   auto_vec<gphi *, 3> lcphis;
-  if (flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
-    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++;
-       else
-         /* We can have more than one loop-closed PHI.  */
-         lcphis.safe_push (as_a <gphi *> (use_stmt));
-       if (nloop_uses > 1)
-         {
-           if (dump_enabled_p ())
-             dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                              "reduction used in loop.\n");
-           return NULL;
-         }
-      }
+  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++;
+      else
+       /* We can have more than one loop-closed PHI.  */
+       lcphis.safe_push (as_a <gphi *> (use_stmt));
+      if (nloop_uses > 1)
+       {
+         if (dump_enabled_p ())
+           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                            "reduction used in loop.\n");
+         return NULL;
+       }
+    }
 
   /* If DEF_STMT is a phi node itself, we expect it to have a single argument
      defined in the inner loop.  */
Index: gcc/testsuite/gcc.dg/torture/pr81510.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr81510.c      (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr81510.c      (working copy)
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-w" } */
+
+typedef int d;
+typedef int f;
+typedef long h;
+int a;
+int b;
+int c;
+int e()
+{
+  f *g;
+  h i;
+  for (;;)
+    if (g)
+      for (; b; b++) {
+         g = c;
+         if (a &= c) {
+             d *j = &b;
+             h k;
+             for (; i; i++) {
+                 *g ?: (*j = k);
+                 g = &a;
+             }
+             for (; i <= 3; i++)
+               ;
+         }
+      }
+}
Index: gcc/testsuite/gcc.dg/torture/pr81510-2.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr81510-2.c    (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr81510-2.c    (working copy)
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+typedef int h;
+typedef int k;
+int a;
+int b;
+int c;
+int d;
+int e;
+int f(int g)
+{
+  h *i = &e;
+  k *j;
+  if (d -= b)
+    for (; *j; *j += 1) {
+       g = g || (a = e ? c = (__UINTPTR_TYPE__)j : 0) + *i;
+       i = &d;
+    }
+}

Reply via email to