This makes the vectorizer use strided accesses when single-element interleaving fails.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2015-10-22 Richard Biener <rguent...@suse.de> PR tree-optimization/19049 PR tree-optimization/65962 * tree-vect-data-refs.c (vect_analyze_group_access_1): Fall back to strided accesses if single-element interleaving doesn't work. * gcc.dg/vect/vect-strided-store-pr65962.c: New testcase. * gcc.dg/vect/vect-63.c: Adjust. * gcc.dg/vect/vect-70.c: Likewise. * gcc.dg/vect/vect-strided-u8-i2-gap.c: Likewise. * gcc.dg/vect/vect-strided-a-u8-i2-gap.c: Likewise. * gfortran.dg/vect/pr19049.f90: Likewise. * gfortran.dg/vect/vect-8.f90: Likewise. Index: gcc/tree-vect-data-refs.c =================================================================== *** gcc/tree-vect-data-refs.c (revision 229167) --- gcc/tree-vect-data-refs.c (working copy) *************** vect_analyze_group_access_1 (struct data *** 2114,2120 **** dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, "not consecutive access "); dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0); - dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); } if (bb_vinfo) --- 2136,2141 ---- *************** vect_analyze_group_access_1 (struct data *** 2124,2130 **** return true; } ! return false; } if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt) --- 2145,2153 ---- return true; } ! dump_printf_loc (MSG_NOTE, vect_location, "using strided accesses\n"); ! STMT_VINFO_STRIDED_P (stmt_info) = true; ! return true; } if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) == stmt) Index: gcc/testsuite/gcc.dg/vect/vect-strided-store-pr65962.c =================================================================== *** gcc/testsuite/gcc.dg/vect/vect-strided-store-pr65962.c (revision 0) --- gcc/testsuite/gcc.dg/vect/vect-strided-store-pr65962.c (working copy) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile } */ + /* { dg-require-effective-target vect_int } */ + + void + loop (int *data) + { + for (int i = 0; i < 256; i++) + data[i * 2] += 7; + } + + /* As we can't use interleaving for the store with gaps we have to + use strided stores. */ + + /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ Index: gcc/testsuite/gcc.dg/vect/vect-63.c =================================================================== *** gcc/testsuite/gcc.dg/vect/vect-63.c (revision 229167) --- gcc/testsuite/gcc.dg/vect/vect-63.c (working copy) *************** int main1 () *** 13,19 **** int ia[N*2][4][N]; /* Multidimensional array. Aligned. ! The first dimension depends on j: not vectorizable. */ for (i = 0; i < N; i++) { for (j = 0; j < N; j++) --- 13,19 ---- int ia[N*2][4][N]; /* Multidimensional array. Aligned. ! The first dimension depends on j: use strided stores. */ for (i = 0; i < N; i++) { for (j = 0; j < N; j++) *************** int main (void) *** 42,45 **** return main1 (); } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ --- 42,45 ---- return main1 (); } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ Index: gcc/testsuite/gcc.dg/vect/vect-70.c =================================================================== *** gcc/testsuite/gcc.dg/vect/vect-70.c (revision 229167) --- gcc/testsuite/gcc.dg/vect/vect-70.c (working copy) *************** int main1 () *** 37,43 **** abort (); } ! /* not consecutive */ for (i = 0; i < N; i++) for (j = 3; j < N-3; j++) { --- 37,43 ---- abort (); } ! /* not consecutive, will use strided stores */ for (i = 0; i < N; i++) for (j = 3; j < N-3; j++) { *************** int main (void) *** 62,68 **** return main1 (); } ! /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable} } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {{! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */ --- 62,68 ---- return main1 (); } ! /* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ /* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable} } } } */ /* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {{! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */ Index: gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2-gap.c =================================================================== --- gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2-gap.c (revision 229166) +++ gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2-gap.c (working copy) @@ -35,7 +35,7 @@ main1 (s *arr) } ptr = arr; - /* Not vectorizable: gap in store. */ + /* gap in store, use strided stores. */ for (i = 0; i < N; i++) { res[i].a = ptr->b; @@ -73,5 +73,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_strided2 } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target vect_strided2 } } } */ Index: gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i2-gap.c =================================================================== --- gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i2-gap.c (revision 229166) +++ gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i2-gap.c (working copy) @@ -44,7 +44,7 @@ main1 () } ptr = arr; - /* Not vectorizable: gap in store. */ + /* gap in store, use strided stores */ for (i = 0; i < N; i++) { res[i].a = ptr->b; @@ -71,5 +71,5 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_strided2 } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target vect_strided2 } } } */ Index: gcc/testsuite/gfortran.dg/vect/pr19049.f90 =================================================================== --- gcc/testsuite/gfortran.dg/vect/pr19049.f90 (revision 229169) +++ gcc/testsuite/gfortran.dg/vect/pr19049.f90 (working copy) @@ -18,7 +18,4 @@ subroutine s111 (ntimes,ld,n,ctime,dtime return end -! { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } -! { dg-final { scan-tree-dump-times "complicated access pattern" 1 "vect" { xfail vect_multiple_sizes } } } -! { dg-final { scan-tree-dump-times "complicated access pattern" 2 "vect" { target vect_multiple_sizes } } } - +! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } Index: gcc/testsuite/gfortran.dg/vect/vect-8.f90 =================================================================== --- gcc/testsuite/gfortran.dg/vect/vect-8.f90 (revision 229169) +++ gcc/testsuite/gfortran.dg/vect/vect-8.f90 (working copy) @@ -703,4 +703,4 @@ CALL track('KERNEL ') RETURN END SUBROUTINE kernel -! { dg-final { scan-tree-dump-times "vectorized 19 loops" 1 "vect" } } +! { dg-final { scan-tree-dump-times "vectorized 20 loops" 1 "vect" } }