diff mbox

Fix PR tree-optimization/49352

Message ID BANLkTik8BmJQH3uC1aavM2Ly1jTYAX9wDg@mail.gmail.com
State Accepted
Headers show

Commit Message

Ira Rosen June 13, 2011, 6:12 a.m. UTC
Hi,

This patch fixes PR 49352 by ignoring debug uses in SLP reduction detection.
While fixing it Jakub also discovered that an incorrect statement may
be analyzed and operands of not commutative operation may be swapped.
The patch fixes those as well.

Bootstrapped and tested on powerpc64-suse-linux.
Committed.

Ira

ChangeLog:

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-13 Jakub Jelinek  <jakub@redhat.com>
                 Ira Rosen  <ira.rosen@linaro.org>

	PR tree-optimization/49352
	* gcc.dg/vect/pr49352.c: New test.
diff mbox

Patch

Index: testsuite/gcc.dg/vect/pr49352.c
===================================================================
--- testsuite/gcc.dg/vect/pr49352.c	(revision 0)
+++ testsuite/gcc.dg/vect/pr49352.c	(revision 0)
@@ -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: tree-vect-loop.c
===================================================================
--- tree-vect-loop.c	(revision 174981)
+++ tree-vect-loop.c	(working copy)
@@ -1710,12 +1710,12 @@  vect_is_slp_reduction (loop_vec_info loop_info, gi
   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, gi
   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, gi
   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;
+	  tree op = gimple_assign_rhs1 (next_stmt);
+          gimple def_stmt = NULL;
 
-              if (TREE_CODE (op) == SSA_NAME)
-                def_stmt = SSA_NAME_DEF_STMT (op);
+          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))
+	  /* 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))))))
-		{
-		  lhs = gimple_assign_lhs (next_stmt);
-		  next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
- 		  continue;
-		}
-
-	      return false;
-	    }
-	  else
+                      && !is_loop_header_bb_p (gimple_bb (def_stmt)))))
 	    {
-              tree op = gimple_assign_rhs2 (next_stmt);
-              gimple def_stmt = NULL;
+	      lhs = gimple_assign_lhs (next_stmt);
+	      next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
+ 	      continue;
+	    }
 
-              if (TREE_CODE (op) == SSA_NAME)
-                def_stmt = SSA_NAME_DEF_STMT (op);
+	  return false;
+	}
+      else
+	{
+          tree op = gimple_assign_rhs2 (next_stmt);
+          gimple def_stmt = NULL;
 
-              /* 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))
+          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))
 		{
-		  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);
+		  fprintf (vect_dump, "swapping oprnds: ");
+		  print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM);
 		}
-	      else
-		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
+	    return false;
         }
 
       lhs = gimple_assign_lhs (next_stmt);
@@ -2273,7 +2270,7 @@  vect_is_simple_reduction_1 (loop_vec_info loop_inf
     }
 
   /* 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: ");