PR tree-optimization/49199
authorirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 30 May 2011 07:15:31 +0000 (07:15 +0000)
committerirar <irar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 30 May 2011 07:15:31 +0000 (07:15 +0000)
        * tree-vect-loop.c (vect_is_slp_reduction): Check that the
        non-reduction operands are either defined in the loop or
        by induction.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/no-scevccp-pr49199.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect.exp
gcc/tree-vect-loop.c

index ad6be6d..c771214 100644 (file)
@@ -1,3 +1,10 @@
+2011-05-30  Ira Rosen  <ira.rosen@linaro.org>
+
+       PR tree-optimization/49199
+       * tree-vect-loop.c (vect_is_slp_reduction): Check that the
+       non-reduction operands are either defined in the loop or
+       by induction.
+
 2011-05-29  Xinliang David Li  <davidxl@google.com>
 
        * opts-global.c (handle_common_deferred_options): Handle new options.
index 9c9b6fb..60230d8 100644 (file)
@@ -1,3 +1,10 @@
+2011-05-30  Ira Rosen  <ira.rosen@linaro.org>
+
+       PR tree-optimization/49199
+       * gcc.dg/vect/no-scevccp-pr49199.c: New test.
+       * gcc.dg/vect/vect.exp: Run no-scevccp-pr* tests with
+       -fno-tree-scev-cprop.
+
 2011-05-29  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/47601
diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-pr49199.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-pr49199.c
new file mode 100644 (file)
index 0000000..0f11142
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+int const_bar (void) __attribute__ ((__const__));
+int pure_bar (void) __attribute__ ((__pure__));
+
+int foo (void)
+{
+  int i = 0, x = 0;
+  for (; i < 100; i++)
+    {
+       x += const_bar ();
+       x += pure_bar ();
+    }
+  return x;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index b783ec3..e0821d0 100644 (file)
@@ -176,6 +176,12 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-vect-*.\[cS\]]]
 # -fno-tree-scev-cprop
 set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
 lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-pr*.\[cS\]]]  \
+        "" $DEFAULT_VECTCFLAGS
+
+# -fno-tree-scev-cprop
+set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
+lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop"
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-outer-*.\[cS\]]]  \
         "" $DEFAULT_VECTCFLAGS
 
index 666bd9b..c9d0c46 100644 (file)
@@ -1700,7 +1700,7 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
   struct loop *loop = (gimple_bb (phi))->loop_father;
   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
   enum tree_code code;
-  gimple current_stmt = NULL, use_stmt = NULL, first;
+  gimple current_stmt = NULL, use_stmt = NULL, first, next_stmt;
   stmt_vec_info use_stmt_info, current_stmt_info;
   tree lhs;
   imm_use_iterator imm_iter;
@@ -1778,36 +1778,92 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
   if (!found || use_stmt != phi || size < 2)
     return false;
 
-  /* Save the chain for further analysis in SLP detection.  */
-  first = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt));
-  VEC_safe_push (gimple, heap, LOOP_VINFO_REDUCTION_CHAINS (loop_info), first);
-  GROUP_SIZE (vinfo_for_stmt (first)) = size;
-
   /* Swap the operands, if needed, to make the reduction operand be the second
      operand.  */
   lhs = PHI_RESULT (phi);
-  current_stmt = first;
-  while (current_stmt)
+  next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt));
+  while (next_stmt)
     {
-      if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
-          && gimple_assign_rhs2 (current_stmt) != lhs)
-        {
-          if (vect_print_dump_info (REPORT_DETAILS))
-            {
-              fprintf (vect_dump, "swapping oprnds: ");
-              print_gimple_stmt (vect_dump, current_stmt, 0, TDF_SLIM);
-            }
+      if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
+       {
+          if (gimple_assign_rhs2 (next_stmt) == lhs)
+           {
+             tree op = gimple_assign_rhs1 (next_stmt);
+              gimple def_stmt = NULL;
+
+              if (TREE_CODE (op) == SSA_NAME)
+                def_stmt = SSA_NAME_DEF_STMT (op);
+
+             /* Check that the other def is either defined in the loop
+                ("vect_internal_def"), or it's an induction (defined by a
+                loop-header phi-node).  */
+             if (code == COND_EXPR
+                  || (def_stmt
+                     && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
+                      && (is_gimple_assign (def_stmt)
+                          || is_gimple_call (def_stmt)
+                          || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
+                              == vect_induction_def
+                          || (gimple_code (def_stmt) == GIMPLE_PHI
+                              && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
+                                  == vect_internal_def
+                              && !is_loop_header_bb_p (gimple_bb (def_stmt))))))
+               {
+                 lhs = gimple_assign_lhs (next_stmt);
+                 next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
+                 continue;
+               }
+
+             return false;
+           }
+         else
+           {
+              tree op = gimple_assign_rhs2 (next_stmt);
+              gimple def_stmt = NULL;
+
+              if (TREE_CODE (op) == SSA_NAME)
+                def_stmt = SSA_NAME_DEF_STMT (op);
+
+              /* Check that the other def is either defined in the loop
+                 ("vect_internal_def"), or it's an induction (defined by a
+                 loop-header phi-node).  */
+              if (code == COND_EXPR
+                  || (def_stmt
+                     && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
+                      && (is_gimple_assign (def_stmt)
+                          || is_gimple_call (def_stmt)
+                          || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
+                              == vect_induction_def
+                          || (gimple_code (def_stmt) == GIMPLE_PHI
+                              && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt))
+                                  == vect_internal_def
+                              && !is_loop_header_bb_p (gimple_bb (def_stmt))))))
+               {
+                 if (vect_print_dump_info (REPORT_DETAILS))
+                   {
+                     fprintf (vect_dump, "swapping oprnds: ");
+                     print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM);
+                   }
 
-          swap_tree_operands (current_stmt,
-                             gimple_assign_rhs1_ptr (current_stmt),
-                              gimple_assign_rhs2_ptr (current_stmt));
-          mark_symbols_for_renaming (current_stmt);
+                 swap_tree_operands (next_stmt,
+                             gimple_assign_rhs1_ptr (next_stmt),
+                              gimple_assign_rhs2_ptr (next_stmt));
+                 mark_symbols_for_renaming (next_stmt);
+               }
+             else
+               return false;
+           }
         }
 
-      lhs = gimple_assign_lhs (current_stmt);
-      current_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (current_stmt));
+      lhs = gimple_assign_lhs (next_stmt);
+      next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
     }
 
+  /* Save the chain for further analysis in SLP detection.  */
+  first = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt));
+  VEC_safe_push (gimple, heap, LOOP_VINFO_REDUCTION_CHAINS (loop_info), first);
+  GROUP_SIZE (vinfo_for_stmt (first)) = size;
+
   return true;
 }