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  <rguent...@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.

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" } } */

Reply via email to