re PR tree-optimization/49352 (-fcompare-debug failure with -O2 -ftree-vectorize)
authorJakub Jelinek <jakub@redhat.com>
Mon, 13 Jun 2011 06:10:20 +0000 (08:10 +0200)
committerIra Rosen <irar@gcc.gnu.org>
Mon, 13 Jun 2011 06:10:20 +0000 (06:10 +0000)
        PR tree-optimization/49352
        * tree-vect-loop.c (vect_is_slp_reduction): Don't count debug
        uses at all, make sure loop_use_stmt after the loop is a def
        stmt of a used SSA_NAME that is the only one defined inside
        of the loop.  Don't check for COND_EXPR and GIMPLE_BINARY_RHS.
        (vect_is_simple_reduction_1): Call vect_is_slp_reduction only
        if check_reduction is true.

Co-Authored-By: Ira Rosen <ira.rosen@linaro.org>
From-SVN: r174982

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

index e0c471b..f93f020 100644 (file)
@@ -1,3 +1,14 @@
+2011-06-13 Jakub Jelinek  <jakub@redhat.com>
+          Ira Rosen  <ira.rosen@linaro.org>
+
+       PR tree-optimization/49352
+       * tree-vect-loop.c (vect_is_slp_reduction): Don't count debug uses at
+       all, make sure loop_use_stmt after the loop is a def stmt of a used
+       SSA_NAME that is the only one defined inside of the loop.  Don't
+       check for COND_EXPR and GIMPLE_BINARY_RHS.
+       (vect_is_simple_reduction_1): Call vect_is_slp_reduction only if
+       check_reduction is true.
+
 2011-06-11  Jan Hubicka  <jh@suse.cz>
 
        PR middle-end/49373
index 1440c9b..cf6f368 100644 (file)
@@ -1,3 +1,9 @@
+2011-06-13 Jakub Jelinek  <jakub@redhat.com>
+          Ira Rosen  <ira.rosen@linaro.org>
+
+       PR tree-optimization/49352
+       * gcc.dg/vect/pr49352.c: New test.
+
 2011-06-12  Tobias Burnus
 
        PR fortran/49324
diff --git a/gcc/testsuite/gcc.dg/vect/pr49352.c b/gcc/testsuite/gcc.dg/vect/pr49352.c
new file mode 100644 (file)
index 0000000..26f364b
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR tree-optimization/49352 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fcompare-debug" } */
+
+int
+foo (int *x, int *y, int n)
+{
+  int i, j;
+  int dot = 0;
+  for (i = 0; i < n; i++)
+    for (j = 0; j < 2; j++)
+      dot += *(x++) * *(y++);
+  return dot;
+}
index 8ff5ad0..dd6cafe 100644 (file)
@@ -1710,12 +1710,12 @@ 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, next_stmt;
+  gimple current_stmt = NULL, loop_use_stmt = NULL, first, next_stmt;
   stmt_vec_info use_stmt_info, current_stmt_info;
   tree lhs;
   imm_use_iterator imm_iter;
   use_operand_p use_p;
-  int nloop_uses, size = 0, nuses;
+  int nloop_uses, size = 0;
   bool found = false;
 
   if (loop != vect_loop)
@@ -1726,66 +1726,68 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
   while (1)
     {
       nloop_uses = 0;
-      nuses = 0;
       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
         {
-          use_stmt = USE_STMT (use_p);
-          nuses++;
+         gimple use_stmt = USE_STMT (use_p);
           if (is_gimple_debug (use_stmt))
             continue;
 
+         use_stmt = USE_STMT (use_p);
+
           /* Check if we got back to the reduction phi.  */
-          if (gimple_code (use_stmt) == GIMPLE_PHI
-              && use_stmt == phi)
+         if (use_stmt == phi)
             {
+             loop_use_stmt = use_stmt;
               found = true;
               break;
             }
 
           if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))
               && vinfo_for_stmt (use_stmt)
-              && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt))
-              && use_stmt != first_stmt)
-            nloop_uses++;
+             && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt)))
+           {
+             loop_use_stmt = use_stmt;
+             nloop_uses++;
+           }
 
           if (nloop_uses > 1)
             return false;
         }
 
-      /* We reached a statement with no uses.  */
-      if (nuses == 0)
-       return false;
-
       if (found)
         break;
 
+      /* We reached a statement with no loop uses.  */
+      if (nloop_uses == 0)
+       return false;
+
       /* This is a loop exit phi, and we haven't reached the reduction phi.  */
-      if (gimple_code (use_stmt) == GIMPLE_PHI)
+      if (gimple_code (loop_use_stmt) == GIMPLE_PHI)
         return false;
 
-      if (!is_gimple_assign (use_stmt)
-          || code != gimple_assign_rhs_code (use_stmt)
-          || !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
+      if (!is_gimple_assign (loop_use_stmt)
+         || code != gimple_assign_rhs_code (loop_use_stmt)
+         || !flow_bb_inside_loop_p (loop, gimple_bb (loop_use_stmt)))
         return false;
 
       /* Insert USE_STMT into reduction chain.  */
-      use_stmt_info = vinfo_for_stmt (use_stmt);
+      use_stmt_info = vinfo_for_stmt (loop_use_stmt);
       if (current_stmt)
         {
           current_stmt_info = vinfo_for_stmt (current_stmt);
-          GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt;
+         GROUP_NEXT_ELEMENT (current_stmt_info) = loop_use_stmt;
           GROUP_FIRST_ELEMENT (use_stmt_info)
             = GROUP_FIRST_ELEMENT (current_stmt_info);
         }
       else
-          GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt;
+       GROUP_FIRST_ELEMENT (use_stmt_info) = loop_use_stmt;
 
-      lhs = gimple_assign_lhs (use_stmt);
-      current_stmt = use_stmt;
+      lhs = gimple_assign_lhs (loop_use_stmt);
+      current_stmt = loop_use_stmt;
       size++;
    }
 
-  if (!found || use_stmt != phi || size < 2)
+  if (!found || loop_use_stmt != phi || size < 2)
     return false;
 
   /* Swap the operands, if needed, to make the reduction operand be the second
@@ -1794,75 +1796,70 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
   next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt));
   while (next_stmt)
     {
-      if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
+      if (gimple_assign_rhs2 (next_stmt) == lhs)
        {
-          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 (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)))))
            {
-             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))
+             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 (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))
+                  || (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))))))
+                      && !is_loop_header_bb_p (gimple_bb (def_stmt)))))
+           {
+             if (vect_print_dump_info (REPORT_DETAILS))
                {
-                 lhs = gimple_assign_lhs (next_stmt);
-                 next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
-                 continue;
+                 fprintf (vect_dump, "swapping oprnds: ");
+                 print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM);
                }
 
-             return false;
+             swap_tree_operands (next_stmt,
+                                 gimple_assign_rhs1_ptr (next_stmt),
+                                  gimple_assign_rhs2_ptr (next_stmt));
+             mark_symbols_for_renaming (next_stmt);
            }
          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 (next_stmt,
-                             gimple_assign_rhs1_ptr (next_stmt),
-                              gimple_assign_rhs2_ptr (next_stmt));
-                 mark_symbols_for_renaming (next_stmt);
-               }
-             else
-               return false;
-           }
+           return false;
         }
 
       lhs = gimple_assign_lhs (next_stmt);
@@ -2273,7 +2270,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
     }
 
   /* Try to find SLP reduction chain.  */
-  if (vect_is_slp_reduction (loop_info, phi, def_stmt))
+  if (check_reduction && vect_is_slp_reduction (loop_info, phi, def_stmt))
     {
       if (vect_print_dump_info (REPORT_DETAILS))
         report_vect_op (def_stmt, "reduction: detected reduction chain: ");