This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Use strided stores when interleaving fails


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]