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