diff mbox

Fix PR67109

Message ID alpine.LSU.2.11.1508050946370.19642@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Aug. 5, 2015, 7:47 a.m. UTC
The following fixes invalid group detection in the vectorizer where
the size doesn't fit an unsigned int.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-08-05  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/67109
	* tree-vect-data-refs.c (vect_analyze_group_access_1): Check
	against too big groups.  Print whether this is a load or store
	group.  Rename from ...
	(vect_analyze_group_access): ... this which is now a wrapper
	dissolving an invalid group.
	(vect_analyze_data_ref_accesses): Print whether this is a load
	or store group.

	* gcc.dg/torture/pr67109.c: New testcase.
	* gcc.dg/vect/vect-119.c: Adjust.
diff mbox

Patch

Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c	(revision 226551)
+++ gcc/tree-vect-data-refs.c	(working copy)
@@ -2012,10 +2012,11 @@  vect_analyze_data_refs_alignment (loop_v
 /* Analyze groups of accesses: check that DR belongs to a group of
    accesses of legal size, step, etc.  Detect gaps, single element
    interleaving, and other special cases. Set grouped access info.
-   Collect groups of strided stores for further use in SLP analysis.  */
+   Collect groups of strided stores for further use in SLP analysis.
+   Worker for vect_analyze_group_access.  */
 
 static bool
-vect_analyze_group_access (struct data_reference *dr)
+vect_analyze_group_access_1 (struct data_reference *dr)
 {
   tree step = DR_STEP (dr);
   tree scalar_type = TREE_TYPE (DR_REF (dr));
@@ -2182,6 +2183,14 @@  vect_analyze_group_access (struct data_r
       if (groupsize == 0)
         groupsize = count + gaps;
 
+      if (groupsize > UINT_MAX)
+	{
+	  if (dump_enabled_p ())
+	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			     "group is too large\n");
+	  return false;
+	}
+
       /* Check that the size of the interleaving is equal to count for stores,
          i.e., that there are no gaps.  */
       if (groupsize != count
@@ -2203,13 +2212,18 @@  vect_analyze_group_access (struct data_r
       if (dump_enabled_p ())
 	{
 	  dump_printf_loc (MSG_NOTE, vect_location,
-			   "Detected interleaving of size %d starting with ",
-			   (int)groupsize);
+			   "Detected interleaving ");
+	  if (DR_IS_READ (dr))
+	    dump_printf (MSG_NOTE, "load ");
+	  else
+	    dump_printf (MSG_NOTE, "store ");
+	  dump_printf (MSG_NOTE, "of size %u starting with ",
+		       (unsigned)groupsize);
 	  dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
 	  if (GROUP_GAP (vinfo_for_stmt (stmt)) != 0)
 	    dump_printf_loc (MSG_NOTE, vect_location,
-			     "There is a gap of %d elements after the group\n",
-			     (int)GROUP_GAP (vinfo_for_stmt (stmt)));
+			     "There is a gap of %u elements after the group\n",
+			     GROUP_GAP (vinfo_for_stmt (stmt)));
 	}
 
       /* SLP: create an SLP data structure for every interleaving group of
@@ -2249,6 +2263,30 @@  vect_analyze_group_access (struct data_r
   return true;
 }
 
+/* Analyze groups of accesses: check that DR belongs to a group of
+   accesses of legal size, step, etc.  Detect gaps, single element
+   interleaving, and other special cases. Set grouped access info.
+   Collect groups of strided stores for further use in SLP analysis.  */
+
+static bool
+vect_analyze_group_access (struct data_reference *dr)
+{
+  if (!vect_analyze_group_access_1 (dr))
+    {
+      /* Dissolve the group if present.  */
+      gimple next, stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (DR_STMT (dr)));
+      while (stmt)
+	{
+	  stmt_vec_info vinfo = vinfo_for_stmt (stmt);
+	  next = GROUP_NEXT_ELEMENT (vinfo);
+	  GROUP_FIRST_ELEMENT (vinfo) = NULL;
+	  GROUP_NEXT_ELEMENT (vinfo) = NULL;
+	  stmt = next;
+	}
+      return false;
+    }
+  return true;
+}
 
 /* Analyze the access pattern of the data-reference DR.
    In case of non-consecutive accesses call vect_analyze_group_access() to
@@ -2598,6 +2636,10 @@  vect_analyze_data_ref_accesses (loop_vec
 	    {
 	      dump_printf_loc (MSG_NOTE, vect_location,
 			       "Detected interleaving ");
+	      if (DR_IS_READ (dra))
+		dump_printf (MSG_NOTE, "load ");
+	      else
+		dump_printf (MSG_NOTE, "store ");
 	      dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
 	      dump_printf (MSG_NOTE,  " and ");
 	      dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
Index: gcc/testsuite/gcc.dg/torture/pr67109.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr67109.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr67109.c	(working copy)
@@ -0,0 +1,19 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-aggressive-loop-optimizations" } */
+
+unsigned int a;
+int b[1], c, d;
+
+void
+fn1 ()
+{
+  for (; d;)
+    {
+      a = c = 0;
+      for (; c < 5; c++)
+	{
+	  b[a] ^= 1;
+	  a--;
+	}
+    }
+}
Index: gcc/testsuite/gcc.dg/vect/vect-119.c
===================================================================
--- gcc/testsuite/gcc.dg/vect/vect-119.c	(revision 226608)
+++ gcc/testsuite/gcc.dg/vect/vect-119.c	(working copy)
@@ -25,4 +25,4 @@  unsigned int foo (const unsigned int x[O
   return sum;
 }
 
-/* { dg-final { scan-tree-dump-times "Detected interleaving of size 2" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Detected interleaving load of size 2" 1 "vect" } } */