diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-23 14:59:57 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-23 14:59:57 +0000 |
commit | 789e6149491ef418f01e2e4ab81cd1fc24d6e147 (patch) | |
tree | 9e7222ca7f57fd727ba128586760fd688dba755e | |
parent | 2a236b316bfbf15330475fe08ea109e0313fd862 (diff) | |
download | gcc-789e6149491ef418f01e2e4ab81cd1fc24d6e147.tar.gz |
2015-03-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/65518
* tree-vect-stmts.c (vectorizable_load): Reject single-element
interleaving cases we generate absymal code for.
* gcc.dg/vect/pr65518.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221595 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr65518.c | 43 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 16 |
4 files changed, 70 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cb657f66fa8..724d13fd0d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2015-03-23 Richard Biener <rguenther@suse.de> + PR tree-optimization/65518 + * tree-vect-stmts.c (vectorizable_load): Reject single-element + interleaving cases we generate absymal code for. + +2015-03-23 Richard Biener <rguenther@suse.de> + PR tree-optimization/65494 * tree-vect-slp.c (vect_build_slp_tree): Do not (re-)allocate matches here. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cafb23b4b27..e6e63d1a10e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2015-03-23 Richard Biener <rguenther@suse.de> + PR tree-optimization/65518 + * gcc.dg/vect/pr65518.c: New testcase. + +2015-03-23 Richard Biener <rguenther@suse.de> + PR tree-optimization/65494 * gcc.dg/vect/pr65494.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/vect/pr65518.c b/gcc/testsuite/gcc.dg/vect/pr65518.c new file mode 100644 index 00000000000..dc400c6d823 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr65518.c @@ -0,0 +1,43 @@ +/* { dg-do run } */
+
+extern void abort (void);
+
+typedef struct giga
+{
+ unsigned int g[16];
+} giga;
+
+unsigned long __attribute__((noinline,noclone))
+addfst(giga const *gptr, int num)
+{
+ unsigned int retval = 0;
+ int i;
+ for (i = 0; i < num; i++)
+ retval += gptr[i].g[0];
+ return retval;
+}
+
+int main ()
+{
+ struct giga g[8];
+ unsigned int n = 1;
+ int i, j;
+ for (i = 0; i < 8; ++i)
+ for (j = 0; j < 16; ++j)
+ {
+ g[i].g[j] = n++;
+ __asm__ volatile ("");
+ }
+ if (addfst (g, 8) != 456)
+ abort ();
+ return 0;
+}
+
+/* We don't want to vectorize the single-element interleaving in the way
+ we currently do that (without ignoring not needed vectors in the
+ gap between gptr[0].g[0] and gptr[1].g[0]), because that's very
+ sub-optimal and causes memory explosion (even though the cost model
+ should reject that in the end). */
+
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops in function" 2 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index e0cebc685b1..de35508d560 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -5780,6 +5780,22 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, gcc_assert (! nested_in_vect_loop && !STMT_VINFO_GATHER_P (stmt_info)); first_stmt = GROUP_FIRST_ELEMENT (stmt_info); + + /* If this is single-element interleaving with an element distance + that leaves unused vector loads around punt - we at least create + very sub-optimal code in that case (and blow up memory, + see PR65518). */ + if (first_stmt == stmt + && !GROUP_NEXT_ELEMENT (stmt_info) + && GROUP_SIZE (stmt_info) > TYPE_VECTOR_SUBPARTS (vectype)) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "single-element interleaving not supported " + "for not adjacent vector loads\n"); + return false; + } + if (!slp && !PURE_SLP_STMT (stmt_info)) { group_size = GROUP_SIZE (vinfo_for_stmt (first_stmt)); |