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

Reply via email to