diff mbox series

Fix PR86991

Message ID alpine.LSU.2.20.1811131455510.1827@zhemvz.fhfr.qr
State New
Headers show
Series Fix PR86991 | expand

Commit Message

Richard Biener Nov. 13, 2018, 1:57 p.m. UTC
This PR shows we have stale reduction groups lying around because
the fixup doesn't work reliably with reduction chains.  Fixed by
delaying the build to after detection is successful.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Richard.

2018-11-13  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/86991
	* tree-vect-loop.c (vect_is_slp_reduction): Delay reduction
	group building until we have successfully detected the SLP
	reduction.
	(vect_is_simple_reduction): Remove fixup code here.

	* gcc.dg/pr86991.c: New testcase.

Comments

Richard Biener Nov. 13, 2018, 4:15 p.m. UTC | #1
On Tue, 13 Nov 2018, Richard Biener wrote:

> 
> This PR shows we have stale reduction groups lying around because
> the fixup doesn't work reliably with reduction chains.  Fixed by
> delaying the build to after detection is successful.
> 
> Bootstrap & regtest running on x86_64-unknown-linux-gnu.

The following slightly fixed is what I have applied.

Richard.

2018-11-13  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/86991
	* tree-vect-loop.c (vect_is_slp_reduction): Delay reduction
	group building until we have successfully detected the SLP
	reduction.
	(vect_is_simple_reduction): Remove fixup code here.

	* gcc.dg/pr86991.c: New testcase.

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	(revision 266071)
+++ gcc/tree-vect-loop.c	(working copy)
@@ -2466,7 +2466,7 @@ vect_is_slp_reduction (loop_vec_info loo
   struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
   enum tree_code code;
   gimple *loop_use_stmt = NULL;
-  stmt_vec_info use_stmt_info, current_stmt_info = NULL;
+  stmt_vec_info use_stmt_info;
   tree lhs;
   imm_use_iterator imm_iter;
   use_operand_p use_p;
@@ -2476,6 +2476,7 @@ vect_is_slp_reduction (loop_vec_info loo
   if (loop != vect_loop)
     return false;
 
+  auto_vec<stmt_vec_info, 8> reduc_chain;
   lhs = PHI_RESULT (phi);
   code = gimple_assign_rhs_code (first_stmt);
   while (1)
@@ -2528,17 +2529,9 @@ vect_is_slp_reduction (loop_vec_info loo
 
       /* Insert USE_STMT into reduction chain.  */
       use_stmt_info = loop_info->lookup_stmt (loop_use_stmt);
-      if (current_stmt_info)
-        {
-	  REDUC_GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt_info;
-          REDUC_GROUP_FIRST_ELEMENT (use_stmt_info)
-            = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
-        }
-      else
-	REDUC_GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt_info;
+      reduc_chain.safe_push (use_stmt_info);
 
       lhs = gimple_assign_lhs (loop_use_stmt);
-      current_stmt_info = use_stmt_info;
       size++;
    }
 
@@ -2548,10 +2541,9 @@ vect_is_slp_reduction (loop_vec_info loo
   /* Swap the operands, if needed, to make the reduction operand be the second
      operand.  */
   lhs = PHI_RESULT (phi);
-  stmt_vec_info next_stmt_info = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
-  while (next_stmt_info)
+  for (unsigned i = 0; i < reduc_chain.length (); ++i)
     {
-      gassign *next_stmt = as_a <gassign *> (next_stmt_info->stmt);
+      gassign *next_stmt = as_a <gassign *> (reduc_chain[i]->stmt);
       if (gimple_assign_rhs2 (next_stmt) == lhs)
 	{
 	  tree op = gimple_assign_rhs1 (next_stmt);
@@ -2565,7 +2557,6 @@ vect_is_slp_reduction (loop_vec_info loo
 	      && vect_valid_reduction_input_p (def_stmt_info))
 	    {
 	      lhs = gimple_assign_lhs (next_stmt);
-	      next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info);
  	      continue;
 	    }
 
@@ -2600,14 +2591,20 @@ vect_is_slp_reduction (loop_vec_info loo
         }
 
       lhs = gimple_assign_lhs (next_stmt);
-      next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info);
     }
 
+  /* Build up the actual chain.  */
+  for (unsigned i = 0; i < reduc_chain.length () - 1; ++i)
+    {
+      REDUC_GROUP_FIRST_ELEMENT (reduc_chain[i]) = reduc_chain[0];
+      REDUC_GROUP_NEXT_ELEMENT (reduc_chain[i]) = reduc_chain[i+1];
+    }
+  REDUC_GROUP_FIRST_ELEMENT (reduc_chain.last ()) = reduc_chain[0];
+  REDUC_GROUP_NEXT_ELEMENT (reduc_chain.last ()) = NULL;
+
   /* Save the chain for further analysis in SLP detection.  */
-  stmt_vec_info first_stmt_info
-    = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
-  LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (first_stmt_info);
-  REDUC_GROUP_SIZE (first_stmt_info) = size;
+  LOOP_VINFO_REDUCTION_CHAINS (loop_info).safe_push (reduc_chain[0]);
+  REDUC_GROUP_SIZE (reduc_chain[0]) = size;
 
   return true;
 }
@@ -3182,16 +3195,6 @@ vect_is_simple_reduction (loop_vec_info
       return def_stmt_info;
     }
 
-  /* Dissolve group eventually half-built by vect_is_slp_reduction.  */
-  stmt_vec_info first = REDUC_GROUP_FIRST_ELEMENT (def_stmt_info);
-  while (first)
-    {
-      stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first);
-      REDUC_GROUP_FIRST_ELEMENT (first) = NULL;
-      REDUC_GROUP_NEXT_ELEMENT (first) = NULL;
-      first = next;
-    }
-
   /* Look for the expression computing loop_arg from loop PHI result.  */
   if (check_reduction_path (vect_location, loop, phi, loop_arg, code))
     return def_stmt_info;
Index: gcc/testsuite/gcc.dg/pr86991.c
===================================================================
--- gcc/testsuite/gcc.dg/pr86991.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr86991.c	(working copy)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int b;
+extern unsigned c[];
+unsigned d;
+long e;
+
+void f()
+{
+  unsigned g, h;
+  for (; d; d += 2) {
+      g = 1;
+      for (; g; g += 3) {
+	  h = 2;
+	  for (; h < 6; h++)
+	    c[h] = c[h] - b - ~e;
+      }
+  }
+}
diff mbox series

Patch

Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	(revision 266071)
+++ gcc/tree-vect-loop.c	(working copy)
@@ -2476,6 +2476,7 @@  vect_is_slp_reduction (loop_vec_info loo
   if (loop != vect_loop)
     return false;
 
+  auto_vec<stmt_vec_info, 8> reduc_chain;
   lhs = PHI_RESULT (phi);
   code = gimple_assign_rhs_code (first_stmt);
   while (1)
@@ -2528,17 +2529,9 @@  vect_is_slp_reduction (loop_vec_info loo
 
       /* Insert USE_STMT into reduction chain.  */
       use_stmt_info = loop_info->lookup_stmt (loop_use_stmt);
-      if (current_stmt_info)
-        {
-	  REDUC_GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt_info;
-          REDUC_GROUP_FIRST_ELEMENT (use_stmt_info)
-            = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
-        }
-      else
-	REDUC_GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt_info;
+      reduc_chain.safe_push (use_stmt_info);
 
       lhs = gimple_assign_lhs (loop_use_stmt);
-      current_stmt_info = use_stmt_info;
       size++;
    }
 
@@ -2548,10 +2541,9 @@  vect_is_slp_reduction (loop_vec_info loo
   /* Swap the operands, if needed, to make the reduction operand be the second
      operand.  */
   lhs = PHI_RESULT (phi);
-  stmt_vec_info next_stmt_info = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
-  while (next_stmt_info)
+  for (unsigned i = 0; i < reduc_chain.length (); ++i)
     {
-      gassign *next_stmt = as_a <gassign *> (next_stmt_info->stmt);
+      gassign *next_stmt = as_a <gassign *> (reduc_chain[i]->stmt);
       if (gimple_assign_rhs2 (next_stmt) == lhs)
 	{
 	  tree op = gimple_assign_rhs1 (next_stmt);
@@ -2565,7 +2557,6 @@  vect_is_slp_reduction (loop_vec_info loo
 	      && vect_valid_reduction_input_p (def_stmt_info))
 	    {
 	      lhs = gimple_assign_lhs (next_stmt);
-	      next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info);
  	      continue;
 	    }
 
@@ -2600,9 +2591,16 @@  vect_is_slp_reduction (loop_vec_info loo
         }
 
       lhs = gimple_assign_lhs (next_stmt);
-      next_stmt_info = REDUC_GROUP_NEXT_ELEMENT (next_stmt_info);
     }
 
+  /* Build up the actual chain.  */
+  for (unsigned i = 0; i < reduc_chain.length () - 1; ++i)
+    {
+      REDUC_GROUP_FIRST_ELEMENT (reduc_chain[i]) = reduc_chain[0];
+      REDUC_GROUP_NEXT_ELEMENT (reduc_chain[i]) = reduc_chain[i+1];
+    }
+  REDUC_GROUP_NEXT_ELEMENT (reduc_chain.last ()) = NULL;
+
   /* Save the chain for further analysis in SLP detection.  */
   stmt_vec_info first_stmt_info
     = REDUC_GROUP_FIRST_ELEMENT (current_stmt_info);
@@ -3182,16 +3196,6 @@  vect_is_simple_reduction (loop_vec_info
       return def_stmt_info;
     }
 
-  /* Dissolve group eventually half-built by vect_is_slp_reduction.  */
-  stmt_vec_info first = REDUC_GROUP_FIRST_ELEMENT (def_stmt_info);
-  while (first)
-    {
-      stmt_vec_info next = REDUC_GROUP_NEXT_ELEMENT (first);
-      REDUC_GROUP_FIRST_ELEMENT (first) = NULL;
-      REDUC_GROUP_NEXT_ELEMENT (first) = NULL;
-      first = next;
-    }
-
   /* Look for the expression computing loop_arg from loop PHI result.  */
   if (check_reduction_path (vect_location, loop, phi, loop_arg, code))
     return def_stmt_info;
Index: gcc/testsuite/gcc.dg/pr86991.c
===================================================================
--- gcc/testsuite/gcc.dg/pr86991.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr86991.c	(working copy)
@@ -0,0 +1,20 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int b;
+extern unsigned c[];
+unsigned d;
+long e;
+
+void f()
+{
+  unsigned g, h;
+  for (; d; d += 2) {
+      g = 1;
+      for (; g; g += 3) {
+	  h = 2;
+	  for (; h < 6; h++)
+	    c[h] = c[h] - b - ~e;
+      }
+  }
+}