PR tree-optimization/49926
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Aug 2011 16:58:20 +0000 (16:58 +0000)
committerirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Aug 2011 16:58:20 +0000 (16:58 +0000)
        * tree-vect-loop.c (vect_is_slp_reduction): Check that a
        statement in a chain doesn't have uses both inside and
        outside the loop.

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

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

index 573f740..1b5e6de 100644 (file)
@@ -1,3 +1,9 @@
+2011-08-01  Ira Rosen  <ira.rosen@linaro.org>
+
+       PR tree-optimization/49926
+       * tree-vect-loop.c (vect_is_slp_reduction): Check that a statement
+       in a chain doesn't have uses both inside and outside the loop.
+
 2011-08-01  Georg-Johann Lay  <avr@gjlay.de>
        
        * config/avr/avr.h (mcu_type_s): Add errata_skip field.
index 480eea6..b1a3122 100644 (file)
@@ -1,3 +1,8 @@
+2011-08-01  Ira Rosen  <ira.rosen@linaro.org>
+
+       PR tree-optimization/49926
+       * gcc.dg/vect/pr49926.c: New test.
+
 2011-08-01  Kirill Yukhin  <kirill.yukhin@intel.com>
 
        * gcc.target/i386/i386.exp (check_effective_target_lzcnt): New.
diff --git a/gcc/testsuite/gcc.dg/vect/pr49926.c b/gcc/testsuite/gcc.dg/vect/pr49926.c
new file mode 100644 (file)
index 0000000..6096817
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+int a, b, c[10];
+
+void
+foo (unsigned int x, int y, int z, int *w)
+{
+  do
+    {
+      *w = z;
+      y = x;
+      if (y)
+        for (b = -4; b; b++)
+          {
+            z = y &= a &= 1;
+            y &= c[b + 4];
+          }
+    }
+  while (1);
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index 63b3469..505a41a 100644 (file)
@@ -1730,7 +1730,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
   tree lhs;
   imm_use_iterator imm_iter;
   use_operand_p use_p;
-  int nloop_uses, size = 0;
+  int nloop_uses, size = 0, n_out_of_loop_uses;
   bool found = false;
 
   if (loop != vect_loop)
@@ -1741,6 +1741,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
   while (1)
     {
       nloop_uses = 0;
+      n_out_of_loop_uses = 0;
       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
         {
          gimple use_stmt = USE_STMT (use_p);
@@ -1757,16 +1758,22 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
               break;
             }
 
-          if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
-              && vinfo_for_stmt (use_stmt)
-             && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt)))
-           {
-             loop_use_stmt = use_stmt;
-             nloop_uses++;
-           }
+          if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
+            {
+              if (vinfo_for_stmt (use_stmt)
+                  && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt)))
+                {
+                  loop_use_stmt = use_stmt;
+                  nloop_uses++;
+                }
+            }
+           else
+             n_out_of_loop_uses++;
 
-          if (nloop_uses > 1)
-            return false;
+           /* There are can be either a single use in the loop or two uses in
+              phi nodes.  */
+           if (nloop_uses > 1 || (n_out_of_loop_uses && nloop_uses))
+             return false;
         }
 
       if (found)