diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/vect')
613 files changed, 32822 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/O-pr46167.c b/gcc/testsuite/gcc.dg/vect/O-pr46167.c new file mode 100644 index 000000000..490ddd457 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O-pr46167.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ + +int foo (char c, int i) +{ + int s = 0; + while (i--) + s += c; + return s; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/O1-pr33854.c b/gcc/testsuite/gcc.dg/vect/O1-pr33854.c new file mode 100644 index 000000000..4d4171fc4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O1-pr33854.c @@ -0,0 +1,22 @@ +/* Testcase by Martin Michlmayr <tbm@cyrius.com> */ +/* { dg-do compile } */ + +extern void *malloc (__SIZE_TYPE__ __size); +typedef struct VMatrix_ VMatrix; +struct VMatrix_ +{ + int dim; + int t2; +}; +void uniform_correlation_matrix (VMatrix * v) +{ + double *xbar = ((void *) 0); + int m = v->dim; + int i; + xbar = malloc (m * sizeof *xbar); + for (i = 0; i < m; i++) + xbar[i] /= m; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/O1-pr41008.c b/gcc/testsuite/gcc.dg/vect/O1-pr41008.c new file mode 100644 index 000000000..bbdea127c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O1-pr41008.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +double heating[2][2]; + +void foo (int, int); + +void map_do() +{ + int jsav, ksav, k, j; + + for(k = 0; k < 2; k++) + for(j = 0; j < 2; j++) + if (heating[k][j] > 0.) + { + jsav = j; + ksav = k; + } + + foo (jsav, ksav); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/O3-pr36098.c b/gcc/testsuite/gcc.dg/vect/O3-pr36098.c new file mode 100644 index 000000000..1c445be9e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O3-pr36098.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +typedef struct { + int iatom[3]; + int blocknr; +} t_sortblock; + +#define DIM 3 + +void foo (int ncons, t_sortblock *sb, int *iatom) +{ + int i, m; + + for(i=0; (i<ncons); i++,iatom+=3) + for(m=0; (m<DIM); m++) + iatom[m]=sb[i].iatom[m]; +} + +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/O3-pr39675-2.c b/gcc/testsuite/gcc.dg/vect/O3-pr39675-2.c new file mode 100644 index 000000000..7d6af7b82 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O3-pr39675-2.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#define N 128 + +int out[N*4], out2[N], in[N*4]; + +void +foo () +{ + int i, a0, a1, a2, a3; + + for (i = 0; i < N; i++) + { + a0 = in[i*4]; + a1 = in[i*4 + 1]; + a2 = in[i*4 + 2]; + a3 = in[i*4 + 3]; + + out[i*4] = a0; + out[i*4 + 1] = a1; + out[i*4 + 2] = a2; + out[i*4 + 3] = a3; + + out2[i] = a0; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_strided_wide } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_strided_wide } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/O3-pr45971.c b/gcc/testsuite/gcc.dg/vect/O3-pr45971.c new file mode 100644 index 000000000..1b7c65c80 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O3-pr45971.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void +foo (int *x, int *y) +{ + int i; + for (i = 0; i < 11; i++) + y[i] = (x[i] == 1) ? i + 1 : -(i + 1); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/O3-pr46077.c b/gcc/testsuite/gcc.dg/vect/O3-pr46077.c new file mode 100644 index 000000000..6546f6e3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O3-pr46077.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void intf_pcmPlayEffect(int *src, int *dst, int size) { + int i; + for (i = 0; i < size; i++) + *dst++ = *src & 0x80 ? (*src++ & 0x7f) : -*src++; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/O3-vect-pr32243.c b/gcc/testsuite/gcc.dg/vect/O3-vect-pr32243.c new file mode 100644 index 000000000..0116c33fb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O3-vect-pr32243.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +typedef struct __GLcontextRec GLcontext; + +struct gl_renderbuffer +{ + struct gl_renderbuffer *Wrapped; + void (*PutValues) (GLcontext * ctx, struct gl_renderbuffer * rb, + int count, const int x[], const int y[], + const void *values, const char *mask); +}; + +void +put_mono_values_s8 (GLcontext * ctx, struct gl_renderbuffer *s8rb, + int count, const int x[], const int y[], + const void *value, const char *mask) +{ + struct gl_renderbuffer *dsrb = s8rb->Wrapped; + int temp[4096], i; + const char val = *((char *) value); + for (i = 0; i < count; i++) + if (!mask || mask[i]) + temp[i] = (temp[i] & 0xffffff) | val; + dsrb->PutValues (ctx, dsrb, count, x, y, temp, mask); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/O3-vect-pr34223.c b/gcc/testsuite/gcc.dg/vect/O3-vect-pr34223.c new file mode 100644 index 000000000..5dd776c3e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/O3-vect-pr34223.c @@ -0,0 +1,33 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +#define M 10 +#define N 3 + +void __attribute__((noinline)) +foo (int n, int *ub, int *uc) +{ + int i, j, tmp1; + + for (i = 0; i < n; i++) + { + tmp1 = 0; + for (j = 0; j < M; j++) + { + tmp1 += uc[i] * ((int)(j << N) / M); + } + ub[i] = tmp1; + } +} + +int main() +{ + int uc[16], ub[16]; + check_vect (); + foo (16, uc, ub); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/Os-vect-95.c b/gcc/testsuite/gcc.dg/vect/Os-vect-95.c new file mode 100644 index 000000000..8f6e53a6f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/Os-vect-95.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +void bar (float *pd, float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + if (pd[i] != 5.0) + abort (); + } + + return; +} + + +int +main1 (int n, float * __restrict__ pd, float * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc) +{ + int i; + + for (i = 0; i < n; i++) + { + pa[i] = pb[i] * pc[i]; + pd[i] = 5.0; + } + + bar (pd,pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float d[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (N,&d[1],a,b,c); + main1 (N-2,&d[1],a,b,c); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c b/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c new file mode 100644 index 000000000..670e45491 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target section_anchors } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +static int a[N][N]; +static int b[N][N]; +static int c[N][N]; + +void clobber(int *); + +int *foo(void) +{ + int i; + int j; + + clobber (&a[0][0]); + clobber (&b[0][0]); + clobber (&c[0][0]); + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + c[j][i] += a[j][i] + c[j][i]; + } + } + return &c[0][0]; +} + +/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" } } */ +/* { dg-final { cleanup-ipa-dump "increase_alignment" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c new file mode 100644 index 000000000..c13ee3b18 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c @@ -0,0 +1,61 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +unsigned int out[N*8]; +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 (int dummy) +{ + int i; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + + for (i = 0; i < N; i++) + { + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + /* Avoid loop vectorization. */ + if (dummy == 32) + abort (); + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + || out[i*8 + 1] != in[i*8 + 1] + || out[i*8 + 2] != in[i*8 + 2] + || out[i*8 + 3] != in[i*8 + 3] + || out[i*8 + 4] != in[i*8 + 4] + || out[i*8 + 5] != in[i*8 + 5] + || out[i*8 + 6] != in[i*8 + 6] + || out[i*8 + 7] != in[i*8 + 7]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (33); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c new file mode 100644 index 000000000..014f80f8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[1]; + unsigned int a0, a1, a2, a3; + + /* Misaligned store. */ + a0 = *pin++ + 23; + a1 = *pin++ + 142; + a2 = *pin++ + 2; + a3 = *pin++ + 31; + + *pout++ = a0 * x; + *pout++ = a1 * y; + *pout++ = a2 * x; + *pout++ = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[1] != (in[0] + 23) * x + || out[2] != (in[1] + 142) * y + || out[3] != (in[2] + 2) * x + || out[4] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" { xfail vect_hw_misalign } } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_hw_misalign } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c new file mode 100644 index 000000000..d329e2b70 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + short a0, a1, a2, a3; + + a0 = *pin++ + 23; + a1 = *pin++ + 142; + a2 = *pin++ + 2; + a3 = *pin++ + 31; + + *pout++ = a0 * x; + *pout++ = a1 * y; + *pout++ = a2 * x; + *pout++ = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */ +/* { dg-final { scan-tree-dump-times "SLP with multiple types" 1 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c new file mode 100644 index 000000000..4e114d5f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c new file mode 100644 index 000000000..fc6b45781 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + /* Not consecutive load with permutation - not supported. */ + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[1] + 2; + a3 = in[3] + 31; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[1] + 2) * x + || out[3] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c new file mode 100644 index 000000000..cab46d609 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + if (x > y) + x = x + y; + else + y = x; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c new file mode 100644 index 000000000..4390753db --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c @@ -0,0 +1,70 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +unsigned int out[N*8]; +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned int arr[N] = {0,1,2,3,4,5,6,7}; + +__attribute__ ((noinline)) int +main1 (int dummy) +{ + int i; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + unsigned int a = 0; + + for (i = 0; i < N; i++) + { + *pout++ = *pin++ + a; + *pout++ = *pin++ + a; + *pout++ = *pin++ + a; + *pout++ = *pin++ + a; + *pout++ = *pin++ + a; + *pout++ = *pin++ + a; + *pout++ = *pin++ + a; + *pout++ = *pin++ + a; + if (arr[i] = i) + a = i; + else + a = 2; + } + + a = 0; + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + a + || out[i*8 + 1] != in[i*8 + 1] + a + || out[i*8 + 2] != in[i*8 + 2] + a + || out[i*8 + 3] != in[i*8 + 3] + a + || out[i*8 + 4] != in[i*8 + 4] + a + || out[i*8 + 5] != in[i*8 + 5] + a + || out[i*8 + 6] != in[i*8 + 6] + a + || out[i*8 + 7] != in[i*8 + 7] + a) + abort (); + + if (arr[i] = i) + a = i; + else + a = 2; + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (33); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c new file mode 100644 index 000000000..a64543f82 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int b[N]; +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + if (x > y) + x = x + y; + else + y = x; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + b[0] = a0; + b[1] = a1; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y + || b[0] != in[0] + 23 + || b[1] != in[1] + 142) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c new file mode 100644 index 000000000..7869e32fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != a0 * x + || out[1] != a1 * y + || out[2] != a2 * x + || out[3] != a3 * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c new file mode 100644 index 000000000..a314626f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned short out[N]; +unsigned short in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +int i; +__attribute__ ((noinline)) int +main1 () +{ + unsigned short *pin = &in[0]; + unsigned short *pout = &out[0]; + + /* A group of 9 shorts - unsupported for now. */ + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + + if (i) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != in[0] + || out[1] != in[1] + || out[2] != in[2] + || out[3] != in[3] + || out[4] != in[4] + || out[5] != in[5] + || out[6] != in[6] + || out[7] != in[7] + || out[8] != in[8]) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c new file mode 100644 index 000000000..20a61a08d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N*8]; +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 (int dummy) +{ + int i; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + + for (i = 0; i < N*2; i++) + { + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + + /* Avoid loop vectorization. */ + if (dummy) + __asm__ volatile ("" : : : "memory"); + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + || out[i*8 + 1] != in[i*8 + 1] + || out[i*8 + 2] != in[i*8 + 2] + || out[i*8 + 3] != in[i*8 + 3] + || out[i*8 + 4] != in[i*8 + 4] + || out[i*8 + 5] != in[i*8 + 5] + || out[i*8 + 6] != in[i*8 + 6] + || out[i*8 + 7] != in[i*8 + 7]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (33); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c new file mode 100644 index 000000000..9991fe399 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int b[N]; +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + if (x > y) + x = x + y; + else + y = x; + + /* Two SLP instances in the basic block. */ + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + b[0] = -a0; + b[1] = -a1; + b[2] = -a2; + b[3] = -a3; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y + || b[0] != -(in[0] + 23) + || b[1] != -(in[1] + 142) + || b[2] != -(in[2] + 2) + || b[3] != -(in[3] + 31)) + + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c new file mode 100644 index 000000000..acd332079 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c @@ -0,0 +1,70 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int b[N]; +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + /* Two SLP instances in one basic block. */ + if (x > y) + x = x + y; + else + y = x; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + b[0] = a0; + b[1] = a1; + b[2] = a2; + b[3] = a3; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y + || b[0] != (in[0] + 23) + || b[1] != (in[1] + 142) + || b[2] != (in[2] + 2) + || b[3] != (in[3] + 31)) + + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c new file mode 100644 index 000000000..2fa2c1b32 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int b[N]; +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + if (x > y) + { + b[0] = a0; + b[1] = a1; + b[2] = a2; + b[3] = a3; + } + else + { + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + } + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if ((x <= y + && (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y)) + || (x > y + && (b[0] != (in[0] + 23) + || b[1] != (in[1] + 142) + || b[2] != (in[2] + 2) + || b[3] != (in[3] + 31)))) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 2 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c new file mode 100644 index 000000000..1c09048ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +int a[N], b[N]; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + + /* This statement is ignored in vectorization of this basic block. */ + a[x] = b [y]; + + a0 = in[0] + 23; + a1 = in[1] + 142; + a2 = in[2] + 2; + a3 = in[3] + 31; + + out[0] = a0 * x; + out[1] = a1 * y; + out[2] = a2 * x; + out[3] = a3 * y; + + if (x) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c new file mode 100644 index 000000000..fee62d7f9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +int i; +__attribute__ ((noinline)) int +main1 () +{ + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + + if (i) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != in[0] + || out[1] != in[1] + || out[2] != in[2] + || out[3] != in[3]) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c new file mode 100644 index 000000000..a7632f983 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned short out[N]; +unsigned short in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +int i; +__attribute__ ((noinline)) int +main1 () +{ + unsigned short *pin = &in[0]; + unsigned short *pout = &out[0]; + + *pout++ = *pin++; + *pout++ = *pin++; + + if (i) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != in[0] + || out[1] != in[1]) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c new file mode 100644 index 000000000..c4a8a881e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned short out[N]; +unsigned short in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + unsigned short *pin = &in[0]; + unsigned short *pout = &out[0]; + + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + + /* Check results. */ + if (out[0] != in[0] + || out[1] != in[1] + || out[2] != in[2] + || out[3] != in[3] + || out[4] != in[4] + || out[5] != in[5] + || out[6] != in[6] + || out[7] != in[7]) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c new file mode 100644 index 000000000..176010ae5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + unsigned int a0, a1, a2, a3; + + a0 = *pin++ + 23; + a1 = *pin++ + 142; + a2 = *pin++ + 2; + a3 = *pin++ + 31; + + *pout++ = a0 * x; + *pout++ = a1 * y; + *pout++ = a2 * x; + *pout++ = a3 * y; + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c new file mode 100644 index 000000000..4f8212211 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + unsigned int a0, a1, a2, a3; + + /* Non isomorphic. */ + a0 = *pin++ + 23; + a1 = *pin++ + 142; + a2 = *pin++ + 2; + a3 = *pin++ * 31; + + *pout++ = a0 * x; + *pout++ = a1 * y; + *pout++ = a2 * x; + *pout++ = a3 * y; + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] * 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c new file mode 100644 index 000000000..b1203f4db --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y, unsigned int *pin, unsigned int *pout) +{ + int i; + unsigned int a0, a1, a2, a3; + + /* pin and pout may alias. But since all the loads are before the first + store the basic block is vectorizable. */ + a0 = *pin++ + 23; + a1 = *pin++ + 142; + a2 = *pin++ + 2; + a3 = *pin++ + 31; + + *pout++ = a0 * x; + *pout++ = a1 * y; + *pout++ = a2 * x; + *pout++ = a3 * y; + + if (i) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3, &in[0], &out[0]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_hw_misalign } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c new file mode 100644 index 000000000..2251275d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y, unsigned int *pin, unsigned int *pout) +{ + int i; + unsigned int a0, a1, a2, a3; + + /* pin and pout may alias, and loads and stores are mixed. The basic block + cannot be vectorized. */ + a0 = *pin++ + 23; + *pout++ = a0 * x; + a1 = *pin++ + 142; + *pout++ = a1 * y; + a2 = *pin++ + 2; + *pout++ = a2 * x; + a3 = *pin++ + 31; + *pout++ = a3 * y; + + if (i) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3, &in[0], &out[0]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c new file mode 100644 index 000000000..62a691e1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int a0, a1, a2, a3; + unsigned int *pin = &in[0]; + unsigned int *pout = &out[0]; + + /* pin and pout are different, so despite the fact that loads and stores + are mixed the basic block is vectorizable. */ + a0 = *pin++ + 23; + *pout++ = a0 * x; + a1 = *pin++ + 142; + *pout++ = a1 * y; + a2 = *pin++ + 2; + *pout++ = a2 * x; + a3 = *pin++ + 31; + *pout++ = a3 * y; + + if (i) + __asm__ volatile ("" : : : "memory"); + + /* Check results. */ + if (out[0] != (in[0] + 23) * x + || out[1] != (in[1] + 142) * y + || out[2] != (in[2] + 2) * x + || out[3] != (in[3] + 31) * y) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_hw_misalign } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c new file mode 100644 index 000000000..5535dee06 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int *pin = &in[1]; + unsigned int *pout = &out[0]; + unsigned int a0, a1, a2, a3; + + /* Misaligned load. */ + a0 = *pin++ + 23; + a1 = *pin++ + 142; + a2 = *pin++ + 2; + a3 = *pin++ + 31; + + *pout++ = a0 * x; + *pout++ = a1 * y; + *pout++ = a2 * x; + *pout++ = a3 * y; + + /* Check results. */ + if (out[0] != (in[1] + 23) * x + || out[1] != (in[2] + 142) * y + || out[2] != (in[3] + 2) * x + || out[3] != (in[4] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-fast-math-vect-pr29925.c b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-fast-math-vect-pr29925.c new file mode 100644 index 000000000..d5c0a1a13 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-fast-math-vect-pr29925.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdlib.h> +#include "../../tree-vect.h" + +__attribute__ ((noinline)) void +interp_pitch(float *exc, float *interp, int pitch, int len) +{ + int i,k; + int maxj; + + maxj=3; + for (i=0;i<len;i++) + { + float tmp = 0; + for (k=0;k<12;k++) + { + tmp += exc[i-pitch+k+maxj-6]; + } + interp[i] = tmp; + } +} + +int main() +{ + float *exc = calloc(136,sizeof(float)); + float *interp = calloc(80,sizeof(float)); + int pitch = -35; + + check_vect (); + + interp_pitch(exc, interp, pitch, 80); + free(exc); + free(interp); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c new file mode 100644 index 000000000..b109be232 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c @@ -0,0 +1,91 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +struct s tmp; + +int main1 () +{ + int i; + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.b[i] = 5; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.b[i] != 5) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.c[i] = 6; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.c[i] != 6) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.d.k[i] = 7; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.d.k[i] != 7) + abort (); + } + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.e.k[i] = 8; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.e.k[i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c new file mode 100644 index 000000000..5676b2470 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +struct test { + char ca[N]; +}; + +extern struct test s; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-68.c b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-68.c new file mode 100644 index 000000000..b916cd91d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-68.c @@ -0,0 +1,88 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 1. unaligned */ + for (i = 0; i < N; i++) + { + tmp1.a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1.a.n[1][2][i] != 5) + abort (); + } + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1.a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1.a.n[1][2][i] != 6) + abort (); + } + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + tmp1.e.n[1][2][i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (tmp1.e.n[1][2][i] != 7) + abort (); + } + + /* 4. unaligned */ + for (i = 3; i < N-3; i++) + { + tmp1.e.n[1][2][i] = 8; + } + + /* check results: */ + for (i = 3; i <N-3; i++) + { + if (tmp1.e.n[1][2][i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-reduc-1char.c b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-reduc-1char.c new file mode 100644 index 000000000..a7b86cebd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-reduc-1char.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +#define DIFF 242 + +unsigned char ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +void +main1 (unsigned char x, unsigned char max_result, unsigned char min_result) +{ + int i; + unsigned char udiff = 2; + unsigned char umax = x; + unsigned char umin = x; + + for (i = 0; i < N; i++) { + udiff += (unsigned char)(ub[i] - uc[i]); + } + + for (i = 0; i < N; i++) { + umax = umax < uc[i] ? uc[i] : umax; + } + + for (i = 0; i < N; i++) { + umin = umin > uc[i] ? uc[i] : umin; + } + + /* check results: */ + if (udiff != DIFF) + abort (); + if (umax != max_result) + abort (); + if (umin != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/i386-costmodel-vect.exp b/gcc/testsuite/gcc.dg/vect/costmodel/i386/i386-costmodel-vect.exp new file mode 100644 index 000000000..c65100601 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/i386-costmodel-vect.exp @@ -0,0 +1,75 @@ +# Copyright (C) 1997, 2004, 2005, 2006, 2007, 2008, 2010 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# Exit immediately if this isn't a x86 target. +if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then { + return +} + +# Set up flags used for tests that don't specify options. +set DEFAULT_VECTCFLAGS "" + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fvect-cost-model" + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +if { ![check_effective_target_sse2] } then { + return +} +lappend DEFAULT_VECTCFLAGS "-msse2" +if [check_sse2_hw_available] { + set dg-do-what-default run +} else { + set dg-do-what-default compile +} + +# Initialize `dg'. +dg-init + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-fast-math-vect*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c new file mode 100644 index 000000000..4e8d71b96 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int *pin = &in[1]; + unsigned int *pout = &out[0]; + unsigned int a0, a1, a2, a3; + + /* Misaligned load. */ + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + *pout++ = *pin++; + + /* Check results. */ + if (out[0] != in[1] + || out[1] != in[2] + || out[2] != in[3] + || out[3] != in[4]) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-fast-math-vect-pr29925.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-fast-math-vect-pr29925.c new file mode 100644 index 000000000..00e631b13 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-fast-math-vect-pr29925.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdlib.h> +#include "../../tree-vect.h" + +__attribute__ ((noinline)) void +interp_pitch(float *exc, float *interp, int pitch, int len) +{ + int i,k; + int maxj; + + maxj=3; + for (i=0;i<len;i++) + { + float tmp = 0; + for (k=0;k<7;k++) + { + tmp += exc[i-pitch+k+maxj-6]; + } + interp[i] = tmp; + } +} + +int main() +{ + float *exc = calloc(126,sizeof(float)); + float *interp = calloc(80,sizeof(float)); + int pitch = -35; + + check_vect (); + + interp_pitch(exc, interp, pitch, 80); + free(exc); + free(interp); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-pr37194.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-pr37194.c new file mode 100644 index 000000000..76c7850fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-pr37194.c @@ -0,0 +1,28 @@ +/* { dg-require-effective-target vect_float } */ +/* { dg-do compile } */ + +#include <stdlib.h> +#include "../../tree-vect.h" + +__attribute__ ((noinline)) void +ggSpectrum_Set8(float * data, float d) +{ + int i; + + for (i = 0; i < 8; i++) + data[i] = d; +} + +__attribute__ ((noinline)) void +ggSpectrum_Set20(float * data, float d) +{ + int i; + + for (i = 0; i < 20; i++) + data[i] = d; +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c new file mode 100644 index 000000000..4d75d565b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-12.c @@ -0,0 +1,119 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + float out2[N*8], fa[N*4]; + unsigned int ia[N], ib[N*2]; + + for (i = 0; i < N; i++) + { + + a0 = in[i*8] + 5; + a1 = in[i*8 + 1] + 6; + a2 = in[i*8 + 2] + 7; + a3 = in[i*8 + 3] + 8; + a4 = in[i*8 + 4] + 9; + a5 = in[i*8 + 5] + 10; + a6 = in[i*8 + 6] + 11; + a7 = in[i*8 + 7] + 12; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + b7 = a7 * 2; + + out[i*8] = b0 - 2; + out[i*8 + 1] = b1 - 3; + out[i*8 + 2] = b2 - 2; + out[i*8 + 3] = b3 - 1; + out[i*8 + 4] = b4 - 8; + out[i*8 + 5] = b5 - 7; + out[i*8 + 6] = b6 - 3; + out[i*8 + 7] = b7 - 7; + + ia[i] = b6; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (in[i*8] + 5) * 3 - 2 + || out[i*8 + 1] != (in[i*8 + 1] + 6) * 2 - 3 + || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 + || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 + || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 + || out[i*8 + 5] != (in[i*8 + 5] + 10) * 4 - 7 + || out[i*8 + 6] != (in[i*8 + 6] + 11) * 3 - 3 + || out[i*8 + 7] != (in[i*8 + 7] + 12) * 2 - 7 + || ia[i] != (in[i*8 + 6] + 11) * 3) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = (in[i*4] + 2) * 3; + out[i*4 + 1] = (in[i*4 + 1] + 2) * 7; + out[i*4 + 2] = (in[i*4 + 2] + 7) * 3; + out[i*4 + 3] = (in[i*4 + 3] + 7) * 7; + + ib[i] = 7; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != (in[i*4] + 2) * 3 + || out[i*4 + 1] != (in[i*4 + 1] + 2) * 7 + || out[i*4 + 2] != (in[i*4 + 2] + 7) * 3 + || out[i*4 + 3] != (in[i*4 + 3] + 7) * 7 + || ib[i] != 7) + abort (); + } + + for (i = 0; i < N*4; i++) + { + out2[i*2] = (float) (in[i*2] * 2 + 11) ; + out2[i*2 + 1] = (float) (in[i*2 + 1] * 3 + 7); + + fa[i] = (float) in[i*2+1]; + } + + /* check results: */ + for (i = 0; i < N*4; i++) + { + if (out2[i*2] != (float) (in[i*2] * 2 + 11) + || out2[i*2 + 1] != (float) (in[i*2 + 1] * 3 + 7) + || fa[i] != (float) in[i*2+1]) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {target { vect_strided && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" {target { vect_strided && vect_int_mult } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c new file mode 100644 index 000000000..9cae12fdb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-33.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + short a; /* aligned */ + char b[N-1]; /* unaligned (offset 2B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* unaligned */ + for (i = 0; i < N/4; i++) + { + tmp.b[2*i] = 5; + tmp.b[2*i+1] = 15; + } + + /* check results: */ + for (i = 0; i <N/4; i++) + { + if (tmp.b[2*i] != 5 + || tmp.b[2*i+1] != 15) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-34.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-34.c new file mode 100644 index 000000000..376c7e4ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-slp-34.c @@ -0,0 +1,74 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +struct mystr { + int f1; + int f2; +}; + +struct mystr af[16] = { + 10, 11, 12, 13, 14, 15, 16, 17, + 20, 21, 22, 23, 24, 25, 26, 27, + 30, 31, 32, 33, 34, 35, 36, 37, + 40, 41, 42, 43, 44, 45, 46, 47 +}; + +struct mystr bf[16] = { + 12, 13, 14, 15, 16, 17, 18, 19, + 22, 23, 24, 25, 26, 27, 28, 29, + 32, 33, 34, 35, 36, 37, 38, 39, + 42, 43, 44, 45, 46, 47, 48, 49 +}; + +struct mystr cf[16]; + +int res1[16] = { + 22, 26, 30, 34, 42, 46, 50, 54, + 62, 66, 70, 74, 82, 86, 90, 94, +}; + +int res2[16] = { + 24, 28, 32, 36, 44, 48, 52, 56, + 64, 68, 72, 76, 84, 88, 92, 96, +}; + +__attribute__ ((noinline)) void +foo (void) +{ + int i; + + for (i = 0; i < 16; i++) + { + cf[i].f1 = af[i].f1 + bf[i].f1; + cf[i].f2 = af[i].f2 + bf[i].f2; + } +} + + + +int +main (void) +{ + int i; + + check_vect (); + foo (); + + /* Check resiults. */ + for (i = 0; i < 16; i++) + { + if (cf[i].f1 != res1[i]) + abort (); + if (cf[i].f2 != res2[i]) + abort (); + + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c new file mode 100644 index 000000000..272b3f0d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.b[i] = 5; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.b[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31b.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31b.c new file mode 100644 index 000000000..b3224f943 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31b.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.c[i] = 6; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.c[i] != 6) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31c.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31c.c new file mode 100644 index 000000000..9dcd09aba --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31c.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.d.k[i] = 7; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.d.k[i] != 7) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-33.c new file mode 100644 index 000000000..11036b0bc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-33.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +struct test { + char ca[N]; +}; + +extern struct test s; + +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + return main1 (); +} + +/* Peeling to align the store is used. Overhead of peeling is too high. */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { target vector_alignment_reachable } } } */ + +/* Versioning to align the store is used. Overhead of versioning is not too high. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target {! vector_alignment_reachable} } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68a.c new file mode 100644 index 000000000..d0d40ac33 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68a.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 1. unaligned */ + for (i = 0; i < N; i++) + { + tmp1.a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1.a.n[1][2][i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68b.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68b.c new file mode 100644 index 000000000..4e52af8b8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68b.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1.a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1.a.n[1][2][i] != 6) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68c.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68c.c new file mode 100644 index 000000000..58c5e9fdb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-68c.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + tmp1.e.n[1][2][i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (tmp1.e.n[1][2][i] != 7) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76a.c new file mode 100644 index 000000000..d11a9a2d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76a.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +#define OFF 4 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + +int main1 (int *pib) +{ + int i; + int ia[N+OFF]; + int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + + for (i = OFF; i < N; i++) + { + ia[i] = pib[i - OFF]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (ia[i] != pib[i - OFF]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (&ib[OFF]); + return 0; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c new file mode 100644 index 000000000..d716b6139 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76b.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +#define OFF 4 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + +int main1 (int *pib) +{ + int i; + int ia[N+OFF]; + int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + + for (i = OFF; i < N; i++) + { + pib[i - OFF] = ic[i]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (pib[i - OFF] != ic[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (&ib[OFF]); + return 0; +} + +/* Peeling to align the store is used. Overhead of peeling is too high. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target vector_alignment_reachable } } } */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { target { vector_alignment_reachable && {! vect_no_align} } } } } */ + +/* Versioning to align the store is used. Overhead of versioning is not too high. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_no_align || {! vector_alignment_reachable} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76c.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76c.c new file mode 100644 index 000000000..1142e7a27 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-76c.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 +#define OFF 4 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; +int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + +int main1 (int *pib) +{ + int i; + int ia[N+OFF]; + + for (i = OFF; i < N; i++) + { + ia[i] = ic[i - OFF]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (ia[i] != ic[i - OFF]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (&ib[OFF]); + return 0; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c new file mode 100644 index 000000000..efab0469b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-outer-fir.c @@ -0,0 +1,71 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 40 +#define M 128 +float in[N+M]; +float coeff[M]; +float out[N]; +float fir_out[N]; + +/* Vectorized. Fixed misaligment in the inner-loop. */ +__attribute__ ((noinline)) void foo (){ + int i,j,k; + float diff; + + for (i = 0; i < N; i++) { + out[i] = 0; + } + + for (k = 0; k < 4; k++) { + for (i = 0; i < N; i++) { + diff = 0; + for (j = k; j < M; j+=4) { + diff += in[j+i]*coeff[j]; + } + out[i] += diff; + } + } +} + +/* Vectorized. Changing misalignment in the inner-loop. */ +__attribute__ ((noinline)) void fir (){ + int i,j,k; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j++) { + diff += in[j+i]*coeff[j]; + } + fir_out[i] = diff; + } +} + + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < M; i++) + coeff[i] = i; + for (i = 0; i < N+M; i++) + in[i] = i; + + foo (); + fir (); + + for (i = 0; i < N; i++) { + if (out[i] != fir_out[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-reduc-1char.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-reduc-1char.c new file mode 100644 index 000000000..55334fdd2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-reduc-1char.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +#define DIFF 242 + +void +main1 (unsigned char x, unsigned char max_result, unsigned char min_result) +{ + int i; + unsigned char ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + unsigned char uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + unsigned char udiff = 2; + unsigned char umax = x; + unsigned char umin = x; + + for (i = 0; i < N; i++) { + udiff += (unsigned char)(ub[i] - uc[i]); + } + + for (i = 0; i < N; i++) { + umax = umax < uc[i] ? uc[i] : umax; + } + + for (i = 0; i < N; i++) { + umin = umin > uc[i] ? uc[i] : umin; + } + + /* check results: */ + if (udiff != DIFF) + abort (); + if (umax != max_result) + abort (); + if (umin != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/ppc-costmodel-vect.exp b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/ppc-costmodel-vect.exp new file mode 100644 index 000000000..280b55668 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/ppc-costmodel-vect.exp @@ -0,0 +1,90 @@ +# Copyright (C) 1997, 2004, 2005, 2006, 2007, 2010 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# Exit immediately if this isn't a powerpc target. +if { ![istarget powerpc*-*-*] } then { + return +} + +# Skip targets not supporting -maltivec. +if ![is-effective-target powerpc_altivec_ok] { + return +} + +# Set up flags used for tests that don't specify options. +set DEFAULT_VECTCFLAGS "" + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fvect-cost-model" + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +lappend DEFAULT_VECTCFLAGS "-maltivec" +if [check_vmx_hw_available] { + set dg-do-what-default run +} else { + if [is-effective-target ilp32] { + # Specify a cpu that supports VMX for compile-only tests. + lappend DEFAULT_VECTCFLAGS "-mcpu=970" + } + set dg-do-what-default compile +} + +# Initialize `dg'. +dg-init + +set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" +lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-pr*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-slp-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-bb-slp*.\[cS\]]] \ + "" $VECT_SLP_CFLAGS + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-fast-math-vect*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-fast-math-vect-pr29925.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-fast-math-vect-pr29925.c new file mode 100644 index 000000000..00e631b13 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-fast-math-vect-pr29925.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdlib.h> +#include "../../tree-vect.h" + +__attribute__ ((noinline)) void +interp_pitch(float *exc, float *interp, int pitch, int len) +{ + int i,k; + int maxj; + + maxj=3; + for (i=0;i<len;i++) + { + float tmp = 0; + for (k=0;k<7;k++) + { + tmp += exc[i-pitch+k+maxj-6]; + } + interp[i] = tmp; + } +} + +int main() +{ + float *exc = calloc(126,sizeof(float)); + float *interp = calloc(80,sizeof(float)); + int pitch = -35; + + check_vect (); + + interp_pitch(exc, interp, pitch, 80); + free(exc); + free(interp); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31a.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31a.c new file mode 100644 index 000000000..272b3f0d7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31a.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.b[i] = 5; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.b[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31b.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31b.c new file mode 100644 index 000000000..b3224f943 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31b.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.c[i] = 6; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.c[i] != 6) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31c.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31c.c new file mode 100644 index 000000000..9dcd09aba --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31c.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.d.k[i] = 7; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.d.k[i] != 7) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31d.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31d.c new file mode 100644 index 000000000..736804fd0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-31d.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +int main1 () +{ + int i; + struct s tmp; + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.e.k[i] = 8; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.e.k[i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-33.c new file mode 100644 index 000000000..11036b0bc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-33.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +struct test { + char ca[N]; +}; + +extern struct test s; + +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + return main1 (); +} + +/* Peeling to align the store is used. Overhead of peeling is too high. */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { target vector_alignment_reachable } } } */ + +/* Versioning to align the store is used. Overhead of versioning is not too high. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target {! vector_alignment_reachable} } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c new file mode 100644 index 000000000..d0d40ac33 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68a.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 1. unaligned */ + for (i = 0; i < N; i++) + { + tmp1.a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1.a.n[1][2][i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68b.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68b.c new file mode 100644 index 000000000..4e52af8b8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68b.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1.a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1.a.n[1][2][i] != 6) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c new file mode 100644 index 000000000..58c5e9fdb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68c.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + tmp1.e.n[1][2][i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (tmp1.e.n[1][2][i] != 7) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c new file mode 100644 index 000000000..9cec93633 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-68d.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 20 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 4. unaligned */ + for (i = 3; i < N-3; i++) + { + tmp1.e.n[1][2][i] = 8; + } + + /* check results: */ + for (i = 3; i <N-3; i++) + { + if (tmp1.e.n[1][2][i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76a.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76a.c new file mode 100644 index 000000000..124493b03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76a.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +#define OFF 4 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + +int main1 (int *pib) +{ + int i; + int ia[N+OFF]; + int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + + for (i = OFF; i < N; i++) + { + ia[i] = pib[i - OFF]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (ia[i] != pib[i - OFF]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (&ib[OFF]); + return 0; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c new file mode 100644 index 000000000..4969a31e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76b.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +#define OFF 4 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 0, 1, 3, 5, 7, 11, 13, 17}; +int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 0, 1, 3, 5, 7, 11, 13, 17}; + +int main1 (int *pib) +{ + int i; + int ia[N+OFF]; + + for (i = OFF; i < N; i++) + { + pib[i - OFF] = ic[i]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (pib[i - OFF] != ic[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (&ib[OFF]); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c new file mode 100644 index 000000000..b42934c68 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-76c.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 +#define OFF 4 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(16))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; +int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + +int main1 (int *pib) +{ + int i; + int ia[N+OFF]; + + for (i = OFF; i < N; i++) + { + ia[i] = ic[i - OFF]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (ia[i] != ic[i - OFF]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (&ib[OFF]); + return 0; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-iv-9.c b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-iv-9.c new file mode 100644 index 000000000..af694a36d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/costmodel-vect-iv-9.c @@ -0,0 +1,38 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 26 +int a[N]; + +__attribute__ ((noinline)) int main1 (int X) +{ + int s = X; + int i; + + /* vectorization of reduction with induction. */ + for (i = 0; i < N; i++) + s += (i + a[i]); + + return s; +} + +int main (void) +{ + int s, i; + check_vect (); + + for (i = 0; i < N; i++) + a[i] = 2*i; + + s = main1 (3); + if (s != 978) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target {! vect_int_mult } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/spu/spu-costmodel-vect.exp b/gcc/testsuite/gcc.dg/vect/costmodel/spu/spu-costmodel-vect.exp new file mode 100644 index 000000000..cde70c54a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/spu/spu-costmodel-vect.exp @@ -0,0 +1,69 @@ +# Copyright (C) 1997, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# Exit immediately if this isn't a powerpc target. +if { ![istarget spu*-*-*] } then { + return +} + + +# Set up flags used for tests that don't specify options. +set DEFAULT_VECTCFLAGS "" + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fvect-cost-model" + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +set dg-do-what-default run + +# Initialize `dg'. +dg-init + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-pr*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-fast-math-vect*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-fast-math-vect-pr29925.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-fast-math-vect-pr29925.c new file mode 100644 index 000000000..d5c0a1a13 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-fast-math-vect-pr29925.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdlib.h> +#include "../../tree-vect.h" + +__attribute__ ((noinline)) void +interp_pitch(float *exc, float *interp, int pitch, int len) +{ + int i,k; + int maxj; + + maxj=3; + for (i=0;i<len;i++) + { + float tmp = 0; + for (k=0;k<12;k++) + { + tmp += exc[i-pitch+k+maxj-6]; + } + interp[i] = tmp; + } +} + +int main() +{ + float *exc = calloc(136,sizeof(float)); + float *interp = calloc(80,sizeof(float)); + int pitch = -35; + + check_vect (); + + interp_pitch(exc, interp, pitch, 80); + free(exc); + free(interp); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr30843.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr30843.c new file mode 100644 index 000000000..5d5d41587 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr30843.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_long } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 + +void dacP98FillRGBMap (unsigned char *pBuffer) +{ + unsigned long dw, dw1; + unsigned long *pdw = (unsigned long *)(pBuffer); + + for( dw = 256, dw1 = 0; dw; dw--, dw1 += 0x01010101) + { + *pdw++ = dw1; + *pdw++ = dw1; + *pdw++ = dw1; + *pdw++ = dw1; + } +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { target vect_interleave +} } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c new file mode 100644 index 000000000..b109be232 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c @@ -0,0 +1,91 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +struct s tmp; + +int main1 () +{ + int i; + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.b[i] = 5; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.b[i] != 5) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.c[i] = 6; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.c[i] != 6) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.d.k[i] = 7; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.d.k[i] != 7) + abort (); + } + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.e.k[i] = 8; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.e.k[i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c new file mode 100644 index 000000000..5676b2470 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +struct test { + char ca[N]; +}; + +extern struct test s; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-68.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-68.c new file mode 100644 index 000000000..b916cd91d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-68.c @@ -0,0 +1,88 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 1. unaligned */ + for (i = 0; i < N; i++) + { + tmp1.a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1.a.n[1][2][i] != 5) + abort (); + } + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1.a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1.a.n[1][2][i] != 6) + abort (); + } + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + tmp1.e.n[1][2][i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (tmp1.e.n[1][2][i] != 7) + abort (); + } + + /* 4. unaligned */ + for (i = 3; i < N-3; i++) + { + tmp1.e.n[1][2][i] = 8; + } + + /* check results: */ + for (i = 3; i <N-3; i++) + { + if (tmp1.e.n[1][2][i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-reduc-1char.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-reduc-1char.c new file mode 100644 index 000000000..a7b86cebd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-reduc-1char.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "../../tree-vect.h" + +#define N 16 +#define DIFF 242 + +unsigned char ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +void +main1 (unsigned char x, unsigned char max_result, unsigned char min_result) +{ + int i; + unsigned char udiff = 2; + unsigned char umax = x; + unsigned char umin = x; + + for (i = 0; i < N; i++) { + udiff += (unsigned char)(ub[i] - uc[i]); + } + + for (i = 0; i < N; i++) { + umax = umax < uc[i] ? uc[i] : umax; + } + + for (i = 0; i < N; i++) { + umin = umin > uc[i] ? uc[i] : umin; + } + + /* check results: */ + if (udiff != DIFF) + abort (); + if (umax != max_result) + abort (); + if (umin != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "vectorization not profitable" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp new file mode 100644 index 000000000..ff3650ce2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/x86_64-costmodel-vect.exp @@ -0,0 +1,75 @@ +# Copyright (C) 1997, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# Exit immediately if this isn't a x86 target. +if { (![istarget x86_64-*-*] && ![istarget i?86-*-*]) + || ![is-effective-target lp64] } then { + return +} + +# Set up flags used for tests that don't specify options. +set DEFAULT_VECTCFLAGS "" + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fvect-cost-model" + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +lappend DEFAULT_VECTCFLAGS "-msse2" +if [check_sse2_hw_available] { + set dg-do-what-default run +} else { + set dg-do-what-default compile +} + +# Initialize `dg'. +dg-init + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-pr*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/costmodel-fast-math-vect*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/vect/dump-tree-dceloop-pr26359.c b/gcc/testsuite/gcc.dg/vect/dump-tree-dceloop-pr26359.c new file mode 100644 index 000000000..ae7aea25e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/dump-tree-dceloop-pr26359.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +int a[256], b[256], c[256]; + +foo () { + int i; + + for (i=0; i<256; i++){ + a[i] = b[i] + c[i]; + } +} + +/* { dg-final { scan-tree-dump-times "Deleting : vect_" 0 "dceloop3" } } */ +/* { dg-final { cleanup-tree-dump "dceloop\[1-3\]" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-pr35982.c b/gcc/testsuite/gcc.dg/vect/fast-math-pr35982.c new file mode 100644 index 000000000..6a01782bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-pr35982.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_intfloat_cvt } */ + +struct mem +{ + float avg; + int len; +}; + +float method2_int16 (struct mem *mem) +{ + int i; + float avg; + + for (i = 0; i < 100; ++i) + avg += mem[i].avg * (float) mem[i].len; + + return avg; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_extract_even_odd_wide } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { xfail vect_extract_even_odd_wide } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-pr43074.c b/gcc/testsuite/gcc.dg/vect/fast-math-pr43074.c new file mode 100644 index 000000000..80077ba7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-pr43074.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +float +pvslockprocess(float *fout, float *fin, int framesize) +{ + int i; + float mag=0.0f, diff; + for (i = 0; i < framesize; i += 2) { + mag += fin[i]; + fout[i] = fin[i]; + fout[i+1] = fin[i+1]; + } + return mag; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-pr44152.c b/gcc/testsuite/gcc.dg/vect/fast-math-pr44152.c new file mode 100644 index 000000000..80ce3dc8d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-pr44152.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +_Complex float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + { 10.0F + 20.0iF, 11.0F + 21.0iF, 12.0F + 22.0iF, 13.0F + 23.0iF, + 14.0F + 24.0iF, 15.0F + 25.0iF, 16.0F + 26.0iF, 17.0F + 27.0iF, + 18.0F + 28.0iF, 19.0F + 29.0iF, 20.0F + 30.0iF, 21.0F + 31.0iF, + 22.0F + 32.0iF, 23.0F + 33.0iF, 24.0F + 34.0iF, 25.0F + 35.0iF }; + +_Complex float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + +__attribute__ ((noinline)) _Complex float +foo (int x) +{ + int i; + _Complex float *p = a + x; + _Complex float sum = 10.0F + 20.0iF; + + for (i = 0; i < N; i++) + { + sum += *p; + p++; + } + + c[0] = sum + 66.0F + 86.0iF; + + return 0; +} + + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-slp-27.c b/gcc/testsuite/gcc.dg/vect/fast-math-slp-27.c new file mode 100644 index 000000000..812400237 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-slp-27.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +float x[2*256+1]; + +void foo(void) +{ + int i; + for (i=0; i<256; ++i) + { + x[2*i] = x[2*i] * x[2*i]; + x[2*i+1] = x[2*i+1] * x[2*i+1]; + } +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { target vect_strided } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-complex-3.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-complex-3.c new file mode 100644 index 000000000..3fcf77e0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-complex-3.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +_Complex float a[N] = + { 10.0F + 20.0iF, 11.0F + 21.0iF, 12.0F + 22.0iF, 13.0F + 23.0iF, + 14.0F + 24.0iF, 15.0F + 25.0iF, 16.0F + 26.0iF, 17.0F + 27.0iF, + 18.0F + 28.0iF, 19.0F + 29.0iF, 20.0F + 30.0iF, 21.0F + 31.0iF, + 22.0F + 32.0iF, 23.0F + 33.0iF, 24.0F + 34.0iF, 25.0F + 35.0iF }; +_Complex float b[N] = + { 30.0F + 40.0iF, 31.0F + 41.0iF, 32.0F + 42.0iF, 33.0F + 43.0iF, + 34.0F + 44.0iF, 35.0F + 45.0iF, 36.0F + 46.0iF, 37.0F + 47.0iF, + 38.0F + 48.0iF, 39.0F + 49.0iF, 40.0F + 50.0iF, 41.0F + 51.0iF, + 42.0F + 52.0iF, 43.0F + 53.0iF, 44.0F + 54.0iF, 45.0F + 55.0iF }; + +_Complex float c[N]; +_Complex float res[N] = + { -500.0F + 1000.0iF, -520.0F + 1102.0iF, + -540.0F + 1208.0iF, -560.0F + 1318.0iF, + -580.0F + 1432.0iF, -600.0F + 1550.0iF, + -620.0F + 1672.0iF, -640.0F + 1798.0iF, + -660.0F + 1928.0iF, -680.0F + 2062.0iF, + -700.0F + 2200.0iF, -720.0F + 2342.0iF, + -740.0F + 2488.0iF, -760.0F + 2638.0iF, + -780.0F + 2792.0iF, -800.0F + 2950.0iF }; + + +__attribute__ ((noinline)) void +foo (void) +{ + int i; + + for (i = 0; i < N; i++) + c[i] = a[i] * b[i]; + +} + +int +main (void) +{ + int i; + check_vect (); + + foo (); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (c[i] != res[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd_wide } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-pow-1.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pow-1.c new file mode 100644 index 000000000..4d000f192 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pow-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +float x[256]; + +void foo(void) +{ + int i; + for (i=0; i<256; ++i) + x[i] = x[i] * x[i]; +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-pow-2.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pow-2.c new file mode 100644 index 000000000..a9d927b3f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pow-2.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ + +typedef double d_type; +struct +{ + d_type x; + d_type y; +} S[100]; + +#define N 16 +d_type foo (d_type t); + +d_type +main1 () +{ + int i; + d_type t; + + for (i = 0; i < N; i++) + { + t = (d_type) i / (d_type) 10; + S[5].x = t * t; + } + return S[5].x; +} + +int +main (void) +{ + d_type tmp = main1 (); +} +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-pr25911.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pr25911.c new file mode 100644 index 000000000..633382f5b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pr25911.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +float bessel_Kn_scaled_small_x(int n) +{ + int k; + float k_term, sum1; + for(k=1; k<=n-1; k++) + { + k_term *= -1/(k * (n-k)); + sum1 += k_term; + } + return sum1; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-pr29925.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pr29925.c new file mode 100644 index 000000000..be2f1a913 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-pr29925.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdlib.h> +#include "tree-vect.h" + +__attribute__ ((noinline)) +void interp_pitch(float *exc, float *interp, int pitch, int len) +{ + int i,k; + int maxj; + + maxj=3; + for (i=0;i<len;i++) + { + float tmp = 0; + for (k=0;k<7;k++) + { + tmp += exc[i-pitch+k+maxj-6]; + } + interp[i] = tmp; + } +} + +int main() +{ + float *exc = calloc(126,sizeof(float)); + float *interp = calloc(80,sizeof(float)); + int pitch = -35; + + check_vect (); + + interp_pitch(exc, interp, pitch, 80); + free(exc); + free(interp); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-5.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-5.c new file mode 100644 index 000000000..377d74b77 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-5.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_float } */ + +/* need -funsafe-math-optimizations to vectorize the summation. + also need -ffinite-math-only to create the min/max expr. */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +int main1 (float x, float max_result) +{ + int i; + float diff = 2; + float max = x; + float min = 10; + + for (i = 0; i < N; i++) { + diff += (b[i] - c[i]); + } + + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != 0) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (100, 100); + main1 (0, 15); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-7.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-7.c new file mode 100644 index 000000000..9f36db2e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-7.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_double } */ + +/* need -funsafe-math-optimizations to vectorize the summation. + also need -ffinite-math-only to create the min/max expr. */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +double b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +double c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +int main1 (double x, double max_result) +{ + int i; + double diff = 2; + double max = x; + double min = 10; + + for (i = 0; i < N; i++) { + diff += (b[i] - c[i]); + } + + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != 0) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (100, 100); + main1 (0, 15); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-8.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-8.c new file mode 100644 index 000000000..43a55f3a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-8.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +#include "tree-vect.h" + +extern float x[128] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +extern float y[128] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +extern float z[128] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +float f (unsigned n) +{ + float ret = 0.0; + unsigned i; + for (i = 0; i < n; i++) + { + float diff = x[i] - y[i]; + ret -= diff * diff * z[i]; + } + return ret; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-9.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-9.c new file mode 100644 index 000000000..eb703f5af --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-reduc-9.c @@ -0,0 +1,30 @@ +/* { dg-require-effective-target vect_float } */ + +#include "tree-vect.h" + +float x[1024]; +float +test (void) +{ + int i; + float gosa = 0.0; + for (i = 0; i < 1024; ++i) + { + float tem = x[i]; + gosa += tem * tem; + } + return gosa; +} + +int main (void) +{ + check_vect (); + + if (test () != 0.0) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/ggc-pr37574.c b/gcc/testsuite/gcc.dg/vect/ggc-pr37574.c new file mode 100644 index 000000000..176aa7eaf --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/ggc-pr37574.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ + +#include <stdarg.h> + +unsigned short in[40 +128]; +int main (void) { + int i = 0, j = 0; + unsigned int diff; + unsigned int s=0,sum=0; + for (i = 0; i < 40;i++) + { + diff = 0; + for (j = 0; j < 128;j+=8) + diff += in[j+i]; + s += ((unsigned short)diff>>3); + } + if (s != sum) + return -1; + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c b/gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c new file mode 100644 index 000000000..c952e7f1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-math-errno-slp-32.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ + +double x[256]; + +void foo(void) +{ + int i; + for (i=0; i<128; ++i) + { + x[2*i] = __builtin_pow (x[2*i], 0.5); + x[2*i+1] = __builtin_pow (x[2*i+1], 0.5); + } +} + +/* { dg-final { scan-tree-dump "pattern recognized" "vect" { xfail spu*-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-math-errno-vect-pow-1.c b/gcc/testsuite/gcc.dg/vect/no-math-errno-vect-pow-1.c new file mode 100644 index 000000000..03de93bf4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-math-errno-vect-pow-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_double } */ + +double x[256]; + +void foo(void) +{ + int i; + for (i=0; i<256; ++i) + x[i] = __builtin_pow (x[i], 0.5); +} + +/* { dg-final { scan-tree-dump "pattern recognized" "vect" { xfail spu*-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-1.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-1.c new file mode 100644 index 000000000..9d8a403fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-1.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j,k=0; + int sum,x; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += (i + j); + i++; + } + a[k++] = sum; + } +} + +int main (void) +{ + int i,j,k=0; + int sum; + + check_vect (); + + foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++){ + sum += (j + i); + i++; + } + if (a[k++] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-2.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-2.c new file mode 100644 index 000000000..9a4fa3f25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-2.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +int a[200*N+N]; + +__attribute__ ((noinline)) void +foo (){ + int i,j; + int sum,s=0; + + for (i = 0; i < 200*N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += (i + j); + i++; + } + a[i] = sum; + } +} + +int main (void) +{ + int i,j,k=0; + int sum,s=0; + + check_vect (); + + foo (); + + /* check results: */ + for (i=0; i<200*N; i++) + { + sum = 0; + for (j = 0; j < N; j++){ + sum += (j + i); + i++; + } + if (a[i] != sum) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-3.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-3.c new file mode 100644 index 000000000..a4755e13a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-3.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum,x; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += (i + j); + } + a[i] = sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++){ + sum += (j + i); + } + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-4.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-4.c new file mode 100644 index 000000000..afd2bc414 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-4.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum,s=0; + + for (i = 0; i < 200*N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += (i + j); + i++; + } + s += sum; + } + return s; +} + +__attribute__ ((noinline)) +int bar (int i, int j) +{ +return (i + j); +} + +int main (void) +{ + int i,j,k=0; + int sum,s=0; + int res; + + check_vect (); + + res = foo (); + + /* check results: */ + for (i=0; i<200*N; i++) + { + sum = 0; + for (j = 0; j < N; j++){ + sum += bar (i, j); + i++; + } + s += sum; + } + if (res != s) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-5.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-5.c new file mode 100644 index 000000000..0246a3cda --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-noreassoc-outer-5.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum,x; + + for (i = 0; i < N; i++) { + sum = 0; + x = a[i]; + for (j = 0; j < N; j++) { + sum += (x + j); + } + a[i] = sum + i + x; + } +} + +int main (void) +{ + int i,j; + int sum; + int aa[N]; + + check_vect (); + + for (i=0; i<N; i++){ + a[i] = i; + aa[i] = i; + } + + foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += (j + aa[i]); + if (a[i] != sum + i + aa[i]) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-1.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-1.c new file mode 100644 index 000000000..01fcbaa95 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +#define N 40 +signed short image[N][N]; +signed short block[N][N]; + +/* memory references in the inner-loop */ + +__attribute__ ((noinline)) unsigned int +foo (){ + int i,j; + unsigned int diff = 0; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + diff += (image[i][j] - block[i][j]); + } + } + return diff; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10.c new file mode 100644 index 000000000..e4d6f23f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; +int b[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum,x,y; + + for (i = 0; i < N/2; i++) { + sum = 0; + x = b[2*i]; + y = b[2*i+1]; + for (j = 0; j < n; j++) { + sum += j; + } + a[2*i] = sum + x; + a[2*i+1] = sum + y; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + b[i] = i; + + foo (N-1); + + /* check results: */ + for (i=0; i<N/2; i++) + { + sum = 0; + for (j = 0; j < N-1; j++) + sum += j; + if (a[2*i] != sum + b[2*i] || a[2*i+1] != sum + b[2*i+1]) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10a.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10a.c new file mode 100644 index 000000000..9a71b498d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10a.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; +int b[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum,x,y; + + if (n<=0) + return 0; + + for (i = 0; i < N/2; i++) { + sum = 0; + x = b[2*i]; + y = b[2*i+1]; + j = 0; + do { + sum += j; + } while (++j < n); + a[2*i] = sum + x; + a[2*i+1] = sum + y; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + b[i] = i; + + foo (N-1); + + /* check results: */ + for (i=0; i<N/2; i++) + { + sum = 0; + for (j = 0; j < N-1; j++) + sum += j; + if (a[2*i] != sum + b[2*i] || a[2*i+1] != sum + b[2*i+1]) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10b.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10b.c new file mode 100644 index 000000000..b28111c22 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-10b.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; +int b[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum,x,y; + + if (n<=0) + return 0; + + for (i = 0; i < N/2; i++) { + sum = 0; + x = b[2*i]; + y = b[2*i+1]; + for (j = 0; j < n; j++) { + sum += j; + } + a[2*i] = sum + x; + a[2*i+1] = sum + y; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + b[i] = i; + + foo (N-1); + + /* check results: */ + for (i=0; i<N/2; i++) + { + sum = 0; + for (j = 0; j < N-1; j++) + sum += j; + if (a[2*i] != sum + b[2*i] || a[2*i+1] != sum + b[2*i+1]) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-11.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-11.c new file mode 100644 index 000000000..16b0cc0c3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-11.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum; + + for (i = 0; i < n; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] = sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (N); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-12.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-12.c new file mode 100644 index 000000000..90ea32ddd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-12.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +int a[N]; +short b[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] = sum; + b[i] = (short)sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum || b[i] != (short)sum) + abort(); + } + + return 0; +} + +/* Until we support multiple types in the inner loop */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-13.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-13.c new file mode 100644 index 000000000..b70aabd84 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-13.c @@ -0,0 +1,67 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned short in[N]; + +__attribute__ ((noinline)) unsigned int +foo (short scale){ + int i; + unsigned short j; + unsigned int sum = 0; + unsigned short sum_j; + + for (i = 0; i < N; i++) { + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + sum += ((unsigned int) in[i] * (unsigned int) sum_j) >> scale; + } + return sum; +} + +__attribute__ ((noinline)) unsigned short +bar (void) +{ + unsigned short j; + unsigned short sum_j; + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + return sum_j; +} + +int main (void) +{ + int i; + unsigned short j, sum_j; + unsigned int sum = 0; + unsigned int res; + + check_vect (); + + for (i=0; i<N; i++){ + in[i] = i; + } + + res = foo (2); + + /* check results: */ + for (i=0; i<N; i++) + { + sum_j = bar (); + sum += ((unsigned int) in[i] * (unsigned int) sum_j) >> 2; + } + if (res != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-14.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-14.c new file mode 100644 index 000000000..d7614dc9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-14.c @@ -0,0 +1,61 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +__attribute__ ((noinline)) unsigned short +foo (short scale){ + int i; + unsigned short j; + unsigned short sum = 0; + unsigned short sum_j; + + for (i = 0; i < N; i++) { + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + sum += sum_j; + } + return sum; +} + +__attribute__ ((noinline)) unsigned short +bar (void) +{ + unsigned short j; + unsigned short sum_j; + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + return sum_j; +} + +int main (void) +{ + int i; + unsigned short j, sum_j; + unsigned short sum = 0; + unsigned short res; + + check_vect (); + + res = foo (2); + + /* check results: */ + for (i=0; i<N; i++) + { + sum_j = bar(); + sum += sum_j; + } + if (res != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-15.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-15.c new file mode 100644 index 000000000..b90167675 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-15.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (int x){ + int i,j; + int sum; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] = sum + i + x; + } +} + +int main (void) +{ + int i,j; + int sum; + int aa[N]; + + check_vect (); + + foo (3); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum + i + 3) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-16.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-16.c new file mode 100644 index 000000000..ea58d395c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-16.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i; + unsigned short j; + int sum = 0; + unsigned short sum_j; + + for (i = 0; i < N; i++) { + sum += i; + + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + a[i] = sum_j + 5; + } + return sum; +} + +int main (void) +{ + int i; + unsigned short j, sum_j; + int sum = 0; + int res; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + res = foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum += i; + + sum_j = 0; + for (j = 0; j < N; j++){ + sum_j += j; + } + if (a[i] != sum_j + 5) + abort(); + } + if (res != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { ! {vect_unpack } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-17.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-17.c new file mode 100644 index 000000000..c11a1aa49 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-17.c @@ -0,0 +1,68 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; +int b[N]; +int c[N]; + +__attribute__ ((noinline)) int +foo (){ + int i; + unsigned short j; + int sum = 0; + unsigned short sum_j; + + for (i = 0; i < N; i++) { + int diff = b[i] - c[i]; + + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + a[i] = sum_j + 5; + + sum += diff; + } + return sum; +} + +int main (void) +{ + int i; + unsigned short j, sum_j; + int sum = 0; + int res; + + check_vect (); + + for (i=0; i<N; i++){ + b[i] = i; + c[i] = 2*i; + } + + res = foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum += (b[i] - c[i]); + + sum_j = 0; + for (j = 0; j < N; j++){ + sum_j += j; + } + if (a[i] != sum_j + 5) + abort(); + } + if (res != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { ! {vect_unpack } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-18.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-18.c new file mode 100644 index 000000000..7a6788a0d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-18.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum; + + for (i = 0; i < N/2; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += j; + } + a[2*i] = sum; + a[2*i+1] = 2*sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (); + + /* check results: */ + for (i=0; i<N/2; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[2*i] != sum || a[2*i+1] != 2*sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { target vect_interleave } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-19.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-19.c new file mode 100644 index 000000000..58bcf0870 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-19.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned short a[N]; +unsigned int b[N]; + +__attribute__ ((noinline)) int +foo (){ + unsigned short i,j; + unsigned short sum; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] = sum; + b[i] = (unsigned int)sum; + } +} + +int main (void) +{ + int i,j; + short sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum || b[i] != (unsigned int)sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { ! {vect_unpack } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-2.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-2.c new file mode 100644 index 000000000..13b37883c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#define N 40 + +int +foo (){ + int i,j; + int diff = 0; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + diff += j; + } + } + return diff; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-20.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-20.c new file mode 100644 index 000000000..18e50874a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-20.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; +int b[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum,x,y; + + for (i = 0; i < N/2; i++) { + sum = 0; + x = b[2*i]; + y = b[2*i+1]; + for (j = 0; j < N; j++) { + sum += j; + } + a[2*i] = sum + x; + a[2*i+1] = sum + y; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + b[i] = i; + + foo (); + + /* check results: */ + for (i=0; i<N/2; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[2*i] != sum + b[2*i] || a[2*i+1] != sum + b[2*i+1]) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-21.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-21.c new file mode 100644 index 000000000..f955e4a12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-21.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i; + unsigned short j; + int sum = 0; + unsigned short sum_j; + + for (i = 0; i < N; i++) { + sum += i; + + sum_j = i; + for (j = 0; j < N; j++) { + sum_j += j; + } + a[i] = sum_j + 5; + } + return sum; +} + +int main (void) +{ + int i; + unsigned short j, sum_j; + int sum = 0; + int res; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + res = foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum += i; + + sum_j = i; + for (j = 0; j < N; j++){ + sum_j += j; + } + if (a[i] != sum_j + 5) + abort(); + } + if (res != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { ! { vect_pack_trunc } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-22.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-22.c new file mode 100644 index 000000000..ac24b05d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-22.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum; + + if (n<=0) + return 0; + + /* inner-loop index j used after the inner-loop */ + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < n; j+=2) { + sum += j; + } + a[i] = sum + j; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (N); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j+=2) + sum += j; + if (a[i] != sum + j) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-3.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-3.c new file mode 100644 index 000000000..15afdfd5d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-3.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum; + + /* inner-loop step > 1 */ + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j+=2) { + sum += j; + } + a[i] = sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j+=2) + sum += j; + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-4.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-4.c new file mode 100644 index 000000000..5cf9ade11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-4.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +/* induction variable k advances through inner and outer loops. */ + +__attribute__ ((noinline)) int +foo (int n){ + int i,j,k=0; + int sum; + + if (n<=0) + return 0; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < n; j+=2) { + sum += k++; + } + a[i] = sum + j; + } +} + +int main (void) +{ + int i,j,k=0; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (N); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j+=2) + sum += k++; + if (a[i] != sum + j) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-5.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-5.c new file mode 100644 index 000000000..338e0283b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-5.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (){ + int i,j; + int sum; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] += sum + i; + } +} + +int main (void) +{ + int i,j; + int sum; + int aa[N]; + + check_vect (); + + for (i=0; i<N; i++){ + a[i] = i; + aa[i] = i; + } + + foo (); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != aa[i] + sum + i) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6-global.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6-global.c new file mode 100644 index 000000000..a87367b3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6-global.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (int * __restrict__ b, int k){ + int i,j; + int sum,x; + + for (i = 0; i < N; i++) { + sum = b[i]; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] = sum; + } + + return a[k]; +} + +int main (void) +{ + int i,j; + int sum; + int b[N]; + int a[N]; + + check_vect (); + + for (i=0; i<N; i++) + b[i] = i + 2; + + for (i=0; i<N; i++) + a[i] = foo (b,i); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = b[i]; + for (j = 0; j < N; j++){ + sum += j; + } + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* "Too many BBs in loop" */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6.c new file mode 100644 index 000000000..70cf520d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-6.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +__attribute__ ((noinline)) int +foo (int * __restrict__ b, int k){ + int i,j; + int sum,x; + int a[N]; + + for (i = 0; i < N; i++) { + sum = b[i]; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] = sum; + } + + return a[k]; +} + +int main (void) +{ + int i,j; + int sum; + int b[N]; + int a[N]; + + check_vect (); + + for (i=0; i<N; i++) + b[i] = i + 2; + + for (i=0; i<N; i++) + a[i] = foo (b,i); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = b[i]; + for (j = 0; j < N; j++){ + sum += j; + } + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { unaligned_stack || vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-7.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-7.c new file mode 100644 index 000000000..9606d300c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-7.c @@ -0,0 +1,75 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned short in[N]; +unsigned short coef[N]; +unsigned short a[N]; + +__attribute__ ((noinline)) unsigned int +foo (short scale){ + int i; + unsigned short j; + unsigned int sum = 0; + unsigned short sum_j; + + for (i = 0; i < N; i++) { + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + a[i] = sum_j; + sum += ((unsigned int) in[i] * (unsigned int) coef[i]) >> scale; + } + return sum; +} + +unsigned short +bar (void) +{ + unsigned short j; + unsigned short sum_j; + + sum_j = 0; + for (j = 0; j < N; j++) { + sum_j += j; + } + + return sum_j; +} + +int main (void) +{ + int i; + unsigned short j, sum_j; + unsigned int sum = 0; + unsigned int res; + + check_vect (); + + for (i=0; i<N; i++){ + in[i] = 2*i; + coef[i] = i; + } + + res = foo (2); + + /* check results: */ + for (i=0; i<N; i++) + { + if (a[i] != bar ()) + abort (); + sum += ((unsigned int) in[i] * (unsigned int) coef[i]) >> 2; + } + if (res != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c new file mode 100644 index 000000000..afa5b3d24 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + + +__attribute__ ((noinline)) int +foo (int *a){ + int i,j; + int sum; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < N; j++) { + sum += j; + } + a[i] = sum; + } +} + +int main (void) +{ + int i,j; + int sum; + int a[N]; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (a); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { ! { vect_element_align } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9.c new file mode 100644 index 000000000..e0031274f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < n; j++) { + sum += j; + } + a[i] = sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (N); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9a.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9a.c new file mode 100644 index 000000000..730600a7a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9a.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum; + + if (n<=0) + return 0; + + for (i = 0; i < N; i++) { + sum = 0; + j = 0; + do { + sum += j; + }while (++j < n); + a[i] = sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (N); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9b.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9b.c new file mode 100644 index 000000000..a8a52b963 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-9b.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 + +int a[N]; + +__attribute__ ((noinline)) int +foo (int n){ + int i,j; + int sum; + + if (n<=0) + return 0; + + for (i = 0; i < N; i++) { + sum = 0; + for (j = 0; j < n; j++) { + sum += j; + } + a[i] = sum; + } +} + +int main (void) +{ + int i,j; + int sum; + + check_vect (); + + for (i=0; i<N; i++) + a[i] = i; + + foo (N); + + /* check results: */ + for (i=0; i<N; i++) + { + sum = 0; + for (j = 0; j < N; j++) + sum += j; + if (a[i] != sum) + abort(); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-slp-30.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-slp-30.c new file mode 100644 index 000000000..547a49d58 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-slp-30.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int +main1 () +{ + int i, j; + unsigned short out[N*8], a[N]; + + for (j = 0; j < N; j++) + { + for (i = 0; i < N; i++) + { + out[i*4] = 8; + out[i*4 + 1] = 18; + out[i*4 + 2] = 28; + out[i*4 + 3] = 38; + } + a[j] = 8; + } + + /* check results: */ + for (j = 0; j < N; j++) + { + for (i = 0; i < N; i++) + { + if (out[i*4] != 8 + || out[i*4 + 1] != 18 + || out[i*4 + 2] != 28 + || out[i*4 + 3] != 38) + abort(); + } + + if (a[j] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-slp-31.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-slp-31.c new file mode 100644 index 000000000..0a2149a45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-slp-31.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int +main1 () +{ + int i, j; + unsigned short out[N*8], a[N][N]; + + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + a[i][j] = 8; + } + out[i*4] = 8; + out[i*4 + 1] = 18; + out[i*4 + 2] = 28; + out[i*4 + 3] = 38; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (a[i][j] != 8) + abort (); + } + if (out[i*4] != 8 + || out[i*4 + 1] != 18 + || out[i*4 + 2] != 28 + || out[i*4 + 3] != 38) + abort(); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-1.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-1.c new file mode 100644 index 000000000..9793a129e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-1.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 26 + +__attribute__ ((noinline)) int main1 (int X) +{ + int s = X; + int i; + + /* vectorization of reduction with induction. + Need -fno-tree-scev-cprop or else the loop is eliminated. */ + for (i = 0; i < N; i++) + s += i; + + return s; +} + +int main (void) +{ + int s; + check_vect (); + + s = main1 (3); + if (s != 328) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-2.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-2.c new file mode 100644 index 000000000..adca5cba5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-2.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int arr1[N]; + int k = 0; + int m = 3, i = 0; + + /* Vectorization of induction that is used after the loop. + Currently vectorizable because scev_ccp disconnects the + use-after-the-loop from the iv def inside the loop. */ + + do { + k = k + 2; + arr1[i] = k; + m = m + k; + i++; + } while (i < N); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr1[i] != 2+2*i) + abort (); + } + + return m + k; +} + +int main (void) +{ + int res; + + check_vect (); + + res = main1 (); + if (res != 32 + 275) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-3.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-3.c new file mode 100644 index 000000000..9bf3b4b76 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-vect-iv-3.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 26 + +__attribute__ ((noinline)) +unsigned int main1 () +{ + unsigned short i; + unsigned int intsum = 0; + + /* vectorization of reduction with induction, and widenning sum: + sum shorts into int. + Need -fno-tree-scev-cprop or else the loop is eliminated. */ + for (i = 0; i < N; i++) + { + intsum += i; + } + + return intsum; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_sum_hi_to_si } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" { target vect_widen_sum_hi_to_si } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c new file mode 100644 index 000000000..21b87a396 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c @@ -0,0 +1,92 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +struct s tmp; +__attribute__ ((noinline)) +int main1 () +{ + int i; + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.b[i] = 5; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.b[i] != 5) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.c[i] = 6; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.c[i] != 6) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.d.k[i] = 7; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.d.k[i] != 7) + abort (); + } + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.e.k[i] = 8; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.e.k[i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 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" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-34.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-34.c new file mode 100644 index 000000000..2eac33e41 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-34.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct { + char ca[N]; +} s; +char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != cb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-36.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-36.c new file mode 100644 index 000000000..947677346 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-36.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct { + char ca[N]; + char cb[N]; +} s; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.cb[i] = 3*i; + __asm__ volatile (""); + } + + for (i = 0; i < N; i++) + { + s.ca[i] = s.cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != s.cb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c new file mode 100644 index 000000000..228110487 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c @@ -0,0 +1,88 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ia[N][4][N+1]; +int ic[N][N][3][N+1]; +int id[N][N][N+4]; + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + + /* Multidimensional array. Not aligned: vectorizable. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + ia[i][1][j] = ib[i]; + } + } + + /* Multidimensional array. Aligned: vectorizable. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + ic[i][1][1][j] = ib[i]; + } + } + + /* Multidimensional array. Not aligned: vectorizable. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + id[i][1][j+1] = ib[i]; + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i][1][j] != ib[i]) + abort(); + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ic[i][1][1][j] != ib[i]) + abort(); + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (id[i][1][j+1] != ib[i]) + abort(); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 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" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-65.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-65.c new file mode 100644 index 000000000..b1e74a9f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-65.c @@ -0,0 +1,85 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define M 4 + +int ib[M][M][N] = {{{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}, + {{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}, + {{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}, + {{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}}; +int ia[M][M][N]; +int ic[N]; + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + + /* Multidimensional array. Aligned. The "inner" dimensions + are invariant in the inner loop. Load and store. */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + ia[i][1][j] = ib[2][i][j]; + } + } + + /* check results: */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i][1][j] != ib[2][i][j]) + abort(); + } + } + + /* Multidimensional array. Aligned. The "inner" dimensions + are invariant in the inner loop. Load. */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + ic[j] = ib[2][i][j]; + } + } + + /* check results: */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + if (ic[j] != ib[2][i][j]) + abort(); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c new file mode 100644 index 000000000..49a9098f7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c @@ -0,0 +1,83 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int ia[8][5][N+2]; +int ic[16][16][5][N+2]; + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + + /* Multidimensional array. Aligned. */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + ia[2][6][j] = 5; + } + } + + /* check results: */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + if (ia[2][6][j] != 5) + abort(); + } + } + /* Multidimensional array. Aligned. */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + ia[3][6][j+2] = 5; + } + + /* check results: */ + for (i = 0; i < 16; i++) + { + for (j = 2; j < N+2; j++) + { + if (ia[3][6][j] != 5) + abort(); + } + } + + /* Multidimensional array. Not aligned. */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + ic[2][1][6][j+1] = 5; + } + } + + /* check results: */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + if (ic[2][1][6][j+1] != 5) + abort(); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 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" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c new file mode 100644 index 000000000..de036e88e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c @@ -0,0 +1,92 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +struct test1 tmp1; + +__attribute__ ((noinline)) +int main1 () +{ + int i,j; + + /* 1. unaligned */ + for (i = 0; i < N; i++) + { + tmp1.a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1.a.n[1][2][i] != 5) + abort (); + } + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1.a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1.a.n[1][2][i] != 6) + abort (); + } + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + tmp1.e.n[1][2][i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (tmp1.e.n[1][2][i] != 7) + abort (); + } + + /* 4. unaligned */ + for (i = 3; i < N-3; i++) + { + tmp1.e.n[1][2][i] = 8; + } + + /* check results: */ + for (i = 3; i <N-3; i++) + { + if (tmp1.e.n[1][2][i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 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" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c new file mode 100644 index 000000000..cc4f26fa6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c @@ -0,0 +1,120 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 12 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct s2{ + int m; + int n[N-1][N-1][N-1]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +struct test2{ + struct s2 a; /* array a.n is unaligned */ + int b; + int c; + struct s2 e; /* array e.n is aligned */ +}; + + +struct test1 tmp1[4]; +struct test2 tmp2[4]; + +__attribute__ ((noinline)) +int main1 () +{ + int i,j; + + /* 1. unaligned (known misalignment) */ + for (i = 0; i < N; i++) + { + tmp1[2].a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1[2].a.n[1][2][i] != 5) + abort (); + } + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1[2].a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1[2].a.n[1][2][i] != 6) + abort (); + } + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + tmp1[2].e.n[1][i][j] = 8; + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (tmp1[2].e.n[1][i][j] != 8) + abort (); + } + } + + /* 4. unaligned (unknown misalignment) */ + for (i = 0; i < N-4; i++) + { + for (j = 0; j < N-4; j++) + { + tmp2[2].e.n[1][i][j] = 8; + } + } + + /* check results: */ + for (i = 0; i < N-4; i++) + { + for (j = 0; j < N-4; j++) + { + if (tmp2[2].e.n[1][i][j] != 8) + abort (); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 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" 2 "vect" { xfail {! vector_alignment_reachable} } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-outer-4h.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-outer-4h.c new file mode 100644 index 000000000..fc99122b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-outer-4h.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ +#include <stdarg.h> +#include "tree-vect.h" + + +#define N 40 +#define M 128 +unsigned short a[M][N]; +unsigned int out[N]; + +/* Outer-loop vectorization. */ + +__attribute__ ((noinline)) +void +foo (){ + int i,j; + unsigned int diff; + + for (i = 0; i < N; i++) { + for (j = 0; j < M; j++) { + a[j][i] = 4; + } + out[i]=5; + } +} + +int main (void) +{ + int i, j; + check_vect (); + + foo (); + + for (i = 0; i < N; i++) { + for (j = 0; j < M; j++) { + if (a[j][i] != 4) + abort (); + } + if (out[i] != 5) + abort (); + } + + return 0; +} + + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-1.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-1.c new file mode 100644 index 000000000..e9d957014 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-1.c @@ -0,0 +1,12 @@ +/* Test for pr30485. */ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_condition } */ +void +foo (float a[32], float b[2][32]) +{ + int i; + for (i = 0; i < 32; i++) + a[i] = (b[0][i] > b[1][i]) ? b[0][i] : b[1][i]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-2.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-2.c new file mode 100644 index 000000000..3971c920a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-2.c @@ -0,0 +1,39 @@ +/* Test for pr30485. */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + float a[N]; + + /* Condition in loop. */ + /* This loop is vectorized on platforms that support vect_condition. */ + for (i = 0; i < N; i++) + { + a[i] = (b[i] > 0 ? b[i] : 0); + } + + for (i = 0; i < N; i++) + { + if (a[i] != b[i]) + abort (); + } + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_condition } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-111.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-111.c new file mode 100644 index 000000000..673346a67 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-111.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + float a[N]; + + /* Condition in loop. */ + /* This loop is vectorized on platforms that support vect_condition. */ + for (i = 0; i < N; i++) + { + a[i] = (b[i] > 0 ? b[i] : 0); + } + + for (i = 0; i < N; i++) + { + if (a[i] != b[i]) + abort (); + } + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target powerpc*-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target i?86-*-* x86_64-*-* ia64-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-11.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-11.c new file mode 100644 index 000000000..a35b7ade8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-11.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +float B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] >= MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-12.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-12.c new file mode 100644 index 000000000..485e88cf3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-12.c @@ -0,0 +1,33 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +float B[N] = {0,0,0,42,42,0,0,0,0,0,42,42,42,42,42,0}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + for (i = 0; i < 16; i++) + A[i] = ( A[i] > MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-13.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-13.c new file mode 100644 index 000000000..58e6dc0a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-13.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +float B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] <= MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-14.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-14.c new file mode 100644 index 000000000..58e6dc0a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-14.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +float B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] <= MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-15.c b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-15.c new file mode 100644 index 000000000..a15a0b127 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-trapping-math-vect-ifcvt-15.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +float B[N] = {42,42,0,0,0,42,42,42,42,42,0,0,0,0,0,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] < MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-dom-vect-bug.c b/gcc/testsuite/gcc.dg/vect/no-tree-dom-vect-bug.c new file mode 100644 index 000000000..d94aa3a64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-tree-dom-vect-bug.c @@ -0,0 +1,30 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +long stack_vars_sorted[32]; + +__attribute__ ((noinline)) int +main1 (long n) +{ + long si; + + for (si = 0; si < n; ++si) + stack_vars_sorted[si] = si; +} + +int main () +{ + long si; + + check_vect (); + main1 (32); + + for (si = 0; si < 32; ++si) + if (stack_vars_sorted[si] != si) + abort (); + + return 0; +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-pre-pr45241.c b/gcc/testsuite/gcc.dg/vect/no-tree-pre-pr45241.c new file mode 100644 index 000000000..289a930cd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-tree-pre-pr45241.c @@ -0,0 +1,20 @@ +/* PR tree-optimization/45241 */ +/* { dg-do compile } */ +/* { dg-options "-ftree-vectorize" } */ + +int +foo (short x) +{ + short i, y; + int sum; + + for (i = 0; i < x; i++) + y = x * i; + + for (i = x; i > 0; i--) + sum += y; + + return sum; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-pre-slp-29.c b/gcc/testsuite/gcc.dg/vect/no-tree-pre-slp-29.c new file mode 100644 index 000000000..e370ef307 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-tree-pre-slp-29.c @@ -0,0 +1,78 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned short in2[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +int +main1 (unsigned short *in) +{ + int i; + unsigned short out[N*8]; + + for (i = 0; i < N; i++) + { + out[i*4] = in[i*4]; + out[i*4 + 1] = in[i*4 + 1]; + out[i*4 + 2] = in[i*4 + 2]; + out[i*4 + 3] = in[i*4 + 3]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != in[i*4] + || out[i*4 + 1] != in[i*4 + 1] + || out[i*4 + 2] != in[i*4 + 2] + || out[i*4 + 3] != in[i*4 + 3]) + abort (); + } + + return 0; +} + +int +main2 (unsigned short * __restrict__ in, unsigned short * __restrict__ out) +{ + int i; + + for (i = 0; i < N; i++) + { + out[i*4] = in[i*4]; + out[i*4 + 1] = in[i*4 + 1]; + out[i*4 + 2] = in[i*4 + 2]; + out[i*4 + 3] = in[i*4 + 3]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != in[i*4] + || out[i*4 + 1] != in[i*4 + 1] + || out[i*4 + 2] != in[i*4 + 2] + || out[i*4 + 3] != in[i*4 + 3]) + abort (); + } + + return 0; +} + +int main (void) +{ + unsigned short out[N*8]; + + check_vect (); + + main1 (&in2[5]); + main2 (&in2[3], &out[3]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c new file mode 100644 index 000000000..349bf8b30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int out[N]; +unsigned int in1[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +unsigned int in2[N] = {10,11,12,13,14,15,16,17,18,19,110,111,112,113,114,115}; + +__attribute__ ((noinline)) int +main1 (unsigned int x, unsigned int y) +{ + int i; + unsigned int *pin1 = &in1[0]; + unsigned int *pin2 = &in2[0]; + unsigned int *pout = &out[0]; + unsigned int a0, a1, a2, a3; + + a0 = *pin2++ - *pin1++ + 23; + a1 = *pin2++ - *pin1++ + 142; + a2 = *pin2++ - *pin1++ + 2; + a3 = *pin2++ - *pin1++ + 31; + + *pout++ = a0 * x; + *pout++ = a1 * y; + *pout++ = a2 * x; + *pout++ = a3 * y; + + /* Check results. */ + if (out[0] != (in2[0] - in1[0] + 23) * x + || out[1] != (in2[1] - in1[1] + 142) * y + || out[2] != (in2[2] - in1[2] + 2) * x + || out[3] != (in2[3] - in1[3] + 31) * y) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (2, 3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "slp" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-pr29145.c b/gcc/testsuite/gcc.dg/vect/no-vfa-pr29145.c new file mode 100644 index 000000000..954474eb9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-pr29145.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +__attribute__ ((noinline)) +void with_restrict(int * __restrict p) +{ + int i; + int *q = p - 2; + + for (i = 0; i < 1000; ++i) { + p[i] = q[i]; + } +} + +__attribute__ ((noinline)) +void without_restrict(int * p) +{ + int i; + int *q = p - 2; + + for (i = 0; i < 1000; ++i) { + p[i] = q[i]; + } +} + +int main(void) +{ + int i; + int a[1002]; + int b[1002]; + + check_vect (); + + for (i = 0; i < 1002; ++i) { + a[i] = b[i] = i; + } + + with_restrict(a + 2); + without_restrict(b + 2); + + for (i = 0; i < 1002; ++i) { + if (a[i] != b[i]) + abort(); + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-101.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-101.c new file mode 100644 index 000000000..1830eb8aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-101.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 9 + +struct extraction +{ + int a[N]; + int b[N]; +}; + +static int a[N] = {1,2,3,4,5,6,7,8,9}; +static int b[N] = {2,3,4,5,6,7,8,9,0}; + +__attribute__ ((noinline)) +int main1 (int x, int y) { + int i; + struct extraction *p; + p = (struct extraction *) malloc (sizeof (struct extraction)); + + /* Not vectorizable: different unknown offset. */ + for (i = 0; i < N; i++) + { + *((int *)p + x + i) = a[i]; + *((int *)p + y + i) = b[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->a[i] != a[i] || p->b[i] != b[i]) + abort(); + } + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (0, N); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "can't determine dependence" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102.c new file mode 100644 index 000000000..e49633e02 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 9 + +struct extraction +{ + int a[N]; + int b[N]; +}; + +static int a[N] = {1,2,3,4,5,6,7,8,9}; +static int b[N] = {2,3,4,5,6,7,8,9,9}; +volatile int foo; + +__attribute__ ((noinline)) +int main1 (int x, int y) { + int i; + struct extraction *p; + p = (struct extraction *) malloc (sizeof (struct extraction)); + + for (i = 0; i < N; i++) + { + p->a[i] = a[i]; + if (foo == 135) + abort (); /* to avoid vectorization */ + } + + /* Not vectorizable: distance 1. */ + for (i = 0; i < N - 1; i++) + { + *((int *)p + x + i + 1) = *((int *)p + x + i); + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->a[i] != 1) + abort(); + } + return 0; +} + +int main (void) +{ + check_vect (); + + foo = 0; + return main1 (0, N); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102a.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102a.c new file mode 100644 index 000000000..da8afaa1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-102a.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 9 + +struct extraction +{ + int a[N]; + int b[N]; +}; + +static int a[N] = {1,2,3,4,5,6,7,8,9}; +static int b[N] = {2,3,4,5,6,7,8,9,9}; +volatile int foo; + +__attribute__ ((noinline)) +int main1 (int x, int y) { + int i; + struct extraction *p; + p = (struct extraction *) malloc (sizeof (struct extraction)); + + for (i = 0; i < N; i++) + { + p->a[i] = a[i]; + if (foo == 135) + abort (); /* to avoid vectorization */ + } + + /* Not vectorizable: distance 1. */ + for (i = 0; i < N - 1; i++) + { + p->a[x + i + 1] = p->a[x + i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->a[i] != 1) + abort(); + } + return 0; +} + +int main (void) +{ + check_vect (); + + foo = 0; + return main1 (0, N); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-37.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-37.c new file mode 100644 index 000000000..dc17239a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-37.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +char x[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +char cb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 (char *y) +{ + struct { + char *p; + char *q; + } s; + int i; + + /* Not vectorized - can't antialias the pointer s.p from the array cb. */ + s.p = y; + for (i = 0; i < N; i++) + { + s.p[i] = cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.p[i] != cb[i]) + abort (); + } + + /* Not vectorized - can't antialias the pointer s.p from the pointer s.q. */ + s.q = cb; + for (i = 0; i < N; i++) + { + s.p[i] = s.q[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.p[i] != s.q[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (x); +} + +/* Currently the loops fail to vectorize due to aliasing problems. + If/when the aliasing problems are resolved, unalignment may + prevent vectorization on some targets. */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "can't determine dependence between" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c new file mode 100644 index 000000000..16a01d1a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c @@ -0,0 +1,94 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + + +__attribute__ ((noinline)) int +main1 (float *pa, float *pb, float *pc) +{ + int i; + float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + for (i = 0; i < N; i++) + { + b[i] = pb[i]; + c[i] = pc[i]; + } + + /* Vectorizable: pa may not alias pb and/or pc, even though their + addresses escape. &pa would need to escape to point to escaped memory. */ + for (i = 0; i < N; i++) + { + pa[i] = b[i] * c[i]; + } + + bar (pa,b,c); + + return 0; +} + +__attribute__ ((noinline)) int +main2 (float *pa, float *pb, float *pc) +{ + int i; + float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + for (i = 0; i < N; i++) + { + b[i] = pb[i]; + c[i] = pc[i]; + } + + /* Vectorizable: pb and pc addresses do not escape. */ + for (i = 0; i < N; i++) + { + pa[i] = b[i] * c[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (b[i] * c[i])) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (a,b,c); + main2 (a,b,c); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 2 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-45.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-45.c new file mode 100644 index 000000000..38328c1fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-45.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (const float *pa, const float *pb, const float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +/* Unaligned pointer accesses, with unknown alignment. + The loop bound is known and divisible by the vectorization factor. + Can't prove that the pointers don't alias. + vect-51.c is similar to this one with one difference: + the loop bound is unknown. + vect-44.c is similar to this one with one difference: + Aliasing is not a problem. */ + +__attribute__ ((noinline)) int +main1 (float *pa, float *pb, float *pc) +{ + int i; + + for (i = 0; i < N; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + float a[N]; + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (a,b,c); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-49.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-49.c new file mode 100644 index 000000000..b883a94a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-49.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +/* Unaligned pointer read accesses, aligned pointer write access. + The loop bound is known and divisible by the vectorization factor. + Can't prove that the pointers don't alias. + vect-53.c is similar to this one with one difference: + the loop bound is unknown. + vect-48.c is similar to this one with one difference: + aliasing is not a problem. */ + +__attribute__ ((noinline)) int +main1 (float *pb, float *pc) +{ + float pa[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + int i; + + for (i = 0; i < N; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + float b[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60}; + float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (b,c); + main1 (&b[1],c); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-51.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-51.c new file mode 100644 index 000000000..df463df6a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-51.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (const float *pa, const float *pb, const float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +/* Unaligned pointer accesses, with unknown alignment. + The loop bound is unknown. + Can't prove that the pointers don't alias. + vect-45.c is similar to this one with one difference: + the loop bound is known. + vect-50.c is similar to this one with one difference: + Aliasing is not a problem. */ + +__attribute__ ((noinline)) int +main1 (int n, float *pa, float *pb, float *pc) +{ + int i; + + for (i = 0; i < n; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + float a[N]; + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (N,a,b,c); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-53.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-53.c new file mode 100644 index 000000000..28deeaeac --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-53.c @@ -0,0 +1,63 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (const float *pa, const float *pb, const float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +/* Unaligned pointer read accesses, aligned pointer write access. + The loop bound is unknown. + Can't prove that the pointers don't alias. + vect-49.c is similar to this one with one difference: + the loop bound is known. + vect-52.c is similar to this one with one difference: + aliasing is not a problem. */ + +__attribute__ ((noinline)) int +main1 (int n, float *pb, float *pc) +{ + float pa[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + int i; + + for (i = 0; i < n; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60}; + float c[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; + + check_vect (); + + main1 (N,&b[1],c); + main1 (N,&b[1],&c[1]); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c new file mode 100644 index 000000000..63d332a39 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-57.c @@ -0,0 +1,75 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <string.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i] != (pb[i+1] * pc[i+1])) + abort (); + } + + return; +} + +__attribute__ ((noinline)) +void foo (float *pb, float *pc) +{ + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + memcpy (pb, b, sizeof (b)); + memcpy (pc, c, sizeof (c)); +} + +/* Unaligned pointer read accesses with known alignment, + and an unaligned write access with unknown alignment. + The loop bound is known and divisible by the vectorization factor. + Can't prove that the pointers don't alias. + vect-61.c is similar to this one with one difference: + the loop bound is unknown. + vect-56.c is similar to this one with two differences: + aliasing is a problem, and the write access is aligned. */ + +__attribute__ ((noinline)) int +main1 (float *pa) +{ + int i; + float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float *pb = b; + float *pc = c; + + foo (pb, pc); + + for (i = 0; i < N/2; i++) + { + pa[i] = pb[i+1] * pc[i+1]; + } + + bar (pa, pb, pc); + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + check_vect (); + main1 (a); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c new file mode 100644 index 000000000..2df45fdfe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-61.c @@ -0,0 +1,77 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <string.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i] != (pb[i+1] * pc[i+1])) + abort (); + } + + return; +} + +__attribute__ ((noinline)) +void foo (float *pb, float *pc) +{ + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + memcpy (pb, b, sizeof (b)); + memcpy (pc, c, sizeof (c)); +} + +/* Unaligned pointer read accesses with known alignment, + and an unaligned write access with unknown alignment. + The loop bound is iunknown. + Can't prove that the pointers don't alias. + vect-57.c is similar to this one with one difference: + the loop bound is known. + vect-60.c is similar to this one with two differences: + aliasing is not a problem, and the write access is unaligned. */ + +__attribute__ ((noinline)) int +main1 (int n , float *pa) +{ + int i; + float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float *pb = b; + float *pc = c; + + foo (pb, pc); + + for (i = 0; i < n/2; i++) + { + pa[i] = pb[i+1] * pc[i+1]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + int n=N; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + check_vect (); + main1 (n,a); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-79.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-79.c new file mode 100644 index 000000000..1a694b33e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-79.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float fa[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float fb[N+4] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0}; +float fc[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 7.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5}; + +/* Like vect-80.c but the pointers are not annotated as restricted, + and therefore can't be antialiased. */ + +__attribute__ ((noinline)) int +main1 (float *pa, float *pb, float *pc) +{ + int i; + float *q = pb + 4; + + for (i = 0; i < N; i++) + { + pa[i] = q[i] * pc[i]; + } + + for (i = 0; i < N; i++) + { + if (pa[i] != q[i] * pc[i]) + abort(); + } + + return 0; +} + + +int main (void) +{ + check_vect (); + + main1 (fa, fb, fc); + + return 0; +} + +/* Currently the loops fail to vectorize due to aliasing problems. + If/when the aliasing problems are resolved, unalignment may + prevent vectorization on some targets. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "can't determine dependence between" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-1.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-1.c new file mode 100644 index 000000000..5679ff765 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-depend-1.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 17 + +int ia[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48}; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48}; +int res[N] = {12,24,36,48,60,72,84,96,108,120,132,144,156,168,180,192,48}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + /* Not vectorizable due to data dependence: dependence distance 1. */ + for (i = 0; i < N - 1; i++) + { + ia[i+1] = ia[i] * 4; + } + + /* check results: */ + for (i = 0; i < N - 1; i++) + { + if (ia[i] != 0) + abort (); + } + + /* Vectorizable. Dependence distance -1. */ + for (i = 0; i < N - 1; i++) + { + ib[i] = ib[i+1] * 4; + } + + /* check results: */ + for (i = 0; i < N - 1; i++) + { + if (ib[i] != res[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect(); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "dependence distance negative" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c new file mode 100644 index 000000000..1a49ef269 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-dv-2.c @@ -0,0 +1,78 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 64 +#define MAX 42 + +extern void abort(void); + +int main () +{ + int A[N]; + int B[N]; + int C[N]; + int D[N]; + int E[N] = {0,1,2,0}; + + int i, j; + + check_vect (); + + for (i = 0; i < N; i++) + { + A[i] = i; + B[i] = i; + C[i] = i; + D[i] = i; + } + + /* Vectorizable */ + for (i = 0; i < N-20; i++) + { + A[i] = A[i+20]; + } + + /* check results: */ + for (i = 0; i < N-20; i++) + { + if (A[i] != D[i+20]) + abort (); + } + + /* Vectorizable */ + for (i = 0; i < 16; i++) + { + B[i] = B[i] + 5; + } + + /* check results: */ + for (i = 0; i < 16; i++) + { + if (B[i] != C[i] + 5) + abort (); + } + + /* Not vectorizable */ + for (i = 0; i < 4; i++) + { + C[i+3] = C[i]; + } + + /* check results: */ + for (i = 0; i < 4; i++) + { + if (C[i] != E[i]) + abort (); + } + + return 0; +} + + +/* The initialization induction loop (with aligned access) is also vectorized. */ +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/nodump-pr23073.c b/gcc/testsuite/gcc.dg/vect/nodump-pr23073.c new file mode 100644 index 000000000..d13279919 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/nodump-pr23073.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +extern struct { + int o[2]; + int p[2]; +} d; + +void C() +{ + int i; + + for( i=0; i<2; ++i ) + { + d.o[i] = 0; + d.p[i] = 0; + } + return; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr16105.c b/gcc/testsuite/gcc.dg/vect/pr16105.c new file mode 100644 index 000000000..c59fe0573 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr16105.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +#define VECTOR_SIZE 512 + +extern void check(const float * __restrict__ v); + +void square(const float * __restrict__ a, + float * __restrict__ out) +{ + unsigned int i; + for (i = 0; i < VECTOR_SIZE; i++) { + float ai = a[i]; + float a2 = ai * ai; + out[i] = a2; + } + check(out); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr18308.c b/gcc/testsuite/gcc.dg/vect/pr18308.c new file mode 100644 index 000000000..02aaed2f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr18308.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-vectorize -funroll-loops" } */ +void foo(); + +void bar(int j) +{ + int i, k=0; + for (i = 0; i < 2; ++i) + if (j) k = 2; + + if (k) foo(); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr18400.c b/gcc/testsuite/gcc.dg/vect/pr18400.c new file mode 100644 index 000000000..50971046f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr18400.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int b[N] = {0,3,6,9,12,15,18,21}; +int a[N]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + a[i] = b[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (a[i] != b[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr18425.c b/gcc/testsuite/gcc.dg/vect/pr18425.c new file mode 100644 index 000000000..08f7b65cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr18425.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* ??? Using "long" isn't quite right; we're testing vectors of pointers here. + But since no extant target supports sizeof(long) != sizeof(void*)... */ +/* { dg-require-effective-target vect_long } */ + +char ** _M_allocate(); +void +_M_fill_insert(unsigned int __n) +{ + char **__new_start = _M_allocate(); + char *__tmp = 0; + for (; __n > 0; --__n, ++__new_start) + *__new_start = __tmp; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr18536.c b/gcc/testsuite/gcc.dg/vect/pr18536.c new file mode 100644 index 000000000..4bf41bec4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr18536.c @@ -0,0 +1,35 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int main1 (short a, short *b) +{ + while (++a < 4) *b++ = 2; + + return 0; +} + +int main (void) +{ + int i = 0; + short x[N]; + + check_vect (); + + main1 (0, x); + + /* check results: */ + while (++i < 4) + { + if (x[i-1] != 2) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr20122.c b/gcc/testsuite/gcc.dg/vect/pr20122.c new file mode 100644 index 000000000..9d21fc600 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr20122.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +short Kernshort[24] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +static void VecBug(short Kernel[8][24]) __attribute__((noinline)); +static void VecBug2(short Kernel[8][24]) __attribute__((noinline)); + +/* Kernel may alias Kernshort - a global array. + Use versioning for aliasing. */ +static void VecBug(short Kernel[8][24]) +{ + int k,i; + for (k = 0; k<8; k++) + for (i = 0; i<24; i++) + Kernshort[i] = Kernel[k][i]; +} + +/* Vectorizable: Kernshort2 is local. */ +static void VecBug2(short Kernel[8][24]) +{ + int k,i; + short Kernshort2[24] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + for (k = 0; k<8; k++) + for (i = 0; i<24; i++) + Kernshort2[i] = Kernel[k][i]; + + for (k = 0; k<8; k++) + for (i = 0; i<24; i++) + if (Kernshort2[i] != Kernel[k][i]) + abort (); +} + +int main (int argc, char **argv) +{ + check_vect (); + + short Kernel[8][24] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + int k,i; + + for (k = 0; k<8; k++) + for (i = 0; i<24; i++) + Kernel[k][i] = 0; + + VecBug(Kernel); + VecBug2(Kernel); + + return 0; +} + +/* The loops in VecBug and VecBug2 require versioning for alignment. + The loop in main is aligned. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr21591.c b/gcc/testsuite/gcc.dg/vect/pr21591.c new file mode 100644 index 000000000..425777738 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr21591.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +struct a +{ + int length; + int a1[256]; +}; + +struct a *malloc1(__SIZE_TYPE__) __attribute__((malloc)); +void free(void*); + +struct a *p, *q, *r; + +void f(void) +{ + struct a *a = malloc1(sizeof(struct a)); + struct a *b = malloc1(sizeof(struct a)); + struct a *c = malloc1(sizeof(struct a)); + int i; + + for (i = 0; i < 256; i++) + { + b->a1[i] = i; + c->a1[i] = i; + } + for (i = 0; i < 256; i++) + { + a->a1[i] = b->a1[i] + c->a1[i]; + } + p = a; + q = b; + r = c; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr21969.c b/gcc/testsuite/gcc.dg/vect/pr21969.c new file mode 100644 index 000000000..388fc3129 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr21969.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +typedef float vsf __attribute__((vector_size(2048))); diff --git a/gcc/testsuite/gcc.dg/vect/pr22480.c b/gcc/testsuite/gcc.dg/vect/pr22480.c new file mode 100644 index 000000000..a7e238f22 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr22480.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_shift } */ + +void +test_1 (void) +{ + static unsigned int bm[16]; + int j; + for (j = 0; j < 16; j++) + bm[j] <<= 8; +} + +void +test_2 (int a) +{ + static unsigned int bm[16]; + int j; + for (j = 0; j < 16; j++) + bm[j] <<= a; +} + +void +test_3 (void) +{ + static unsigned bm[16]; + int am[16]; + int j; + for (j = 0; j < 16;j++) + bm[j] <<= am[j]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr22506.c b/gcc/testsuite/gcc.dg/vect/pr22506.c new file mode 100644 index 000000000..5a2d74995 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr22506.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +float x[3]; + +void foo() +{ + int i; + + for (i=0; i<5; ++i) x[i]=0; + for (i=0; i<4; ++i) ; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr23816-1.c b/gcc/testsuite/gcc.dg/vect/pr23816-1.c new file mode 100644 index 000000000..9c76d2e9d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr23816-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_condition } */ + +void +foo (float a[32], float b[2][32]) +{ + int i; + for (i = 0; i < 32; i++) + a[i] = (b[0][i] > b[1][i]) ? b[0][i] : b[1][i]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr23816-2.c b/gcc/testsuite/gcc.dg/vect/pr23816-2.c new file mode 100644 index 000000000..408eb4972 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr23816-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_condition } */ + +void +foo (double a[32], double b[2][32]) +{ + int i; + for (i = 0; i < 32; i++) + a[i] = (b[0][i] > b[1][i]) ? b[0][i] : b[1][i]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr23831.c b/gcc/testsuite/gcc.dg/vect/pr23831.c new file mode 100644 index 000000000..dfa21ce0a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr23831.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void foo (void) +{ + static unsigned int bm[16]; + int j; + for (j = 0; j < 16; j++) + bm[j] = bm[j] * 8; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr24049.c b/gcc/testsuite/gcc.dg/vect/pr24049.c new file mode 100644 index 000000000..ee03fe3ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr24049.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -ftree-vectorize --param ggc-min-heapsize=0 --param ggc-min-expand=0" } */ + +int DES_CBCUpdate(unsigned char * output, int len) +{ + int work[2]; + unsigned int i; + for(i = 0;i < len/8;i++) + unscrunch (&output[8*i], work); +} diff --git a/gcc/testsuite/gcc.dg/vect/pr24059.c b/gcc/testsuite/gcc.dg/vect/pr24059.c new file mode 100644 index 000000000..0849d15c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr24059.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_condition } */ + +struct pred_data +{ + unsigned char codes[((int) 100)]; +}; + +void compute_predicate_codes (char *codes, struct pred_data *p) +{ + int i; + for (i = 0; i < ((int) 100); i++) + codes[i] = p->codes[i] ? 2 : 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr24300.c b/gcc/testsuite/gcc.dg/vect/pr24300.c new file mode 100644 index 000000000..7a79e96c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr24300.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ + +static int *** foo (int); + +void +bar () +{ + int ***p = foo (2); +} + +extern int *nd; +extern int ***tc; +extern int *ap; +extern int *as; +extern float ss; + +static int *** +foo (int Fc) +{ + int i, j, s, p, n, t; + + n = 0; + for (s = 0; s < 4; s++) + n += nd[s]; + + for (i = 0; i < n; i++) + { + p = ap[i]; + s = as[i]; + for (j = 0; j < Fc; j++) + tc[p][s][j] = i * ss + j; + } + + return (tc); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr25371.c b/gcc/testsuite/gcc.dg/vect/pr25371.c new file mode 100644 index 000000000..ad962f47c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr25371.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +void slow_close(int n) +{ + int i; + double *mm; + + for (i=0;i<2*n;i++) + for (i=0;i<2*n;i++) + *(mm+i*2*n+i) = 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr25413.c b/gcc/testsuite/gcc.dg/vect/pr25413.c new file mode 100644 index 000000000..e48373268 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr25413.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +struct +{ + char c; + double d[N]; +} a; + +__attribute__ ((noinline)) +int main1() +{ + int i; + for ( i=0; i<N; ++i ) + a.d[i]=1; + return 0; +} + +int main (void) +{ + int i; + check_vect (); + + main1 (); + for (i=0; i<N; i++) + if (a.d[i] != 1) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vector_alignment_reachable_for_64bit } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { {! vector_alignment_reachable_for_64bit} && {! vect_hw_misalign} } } } } */ +/* { dg-final { scan-tree-dump-times "vector alignment may not be reachable" 1 "vect" { target { {! vector_alignment_reachable_for_64bit} && {! vect_hw_misalign} } } } } */ +/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 1 "vect" { target { {! vector_alignment_reachable_for_64bit} && {! vect_hw_misalign} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr25413a.c b/gcc/testsuite/gcc.dg/vect/pr25413a.c new file mode 100644 index 000000000..b9bef5f5b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr25413a.c @@ -0,0 +1,129 @@ +/* { dg-require-effective-target vect_double } */ + +#include "tree-vect.h" + +#define N 8 + +typedef __SIZE_TYPE__ size_t; + +extern void *malloc (size_t __size) __attribute__ ((__nothrow__, + __malloc__)); + +typedef double num_t; +static const num_t num__infty = ((num_t)1.0)/((num_t)0.0); + +struct oct_tt; +typedef struct oct_tt oct_t; + +typedef unsigned int var_t; +typedef enum { + OCT_EMPTY = 0, + OCT_NORMAL = 1, + OCT_CLOSED = 2 +} oct_state; + +struct oct_tt { + var_t n; + + int ref; + + oct_state state; + struct oct_tt* closed; + + num_t* c; +}; + +void* octfapg_mm_malloc (size_t t); +oct_t* octfapg_alloc (var_t n); +oct_t* octfapg_full_copy (oct_t* m); + +struct mmalloc_tt; +typedef struct mmalloc_tt mmalloc_t; + +struct mmalloc_tt +{ + int id; + + int nb_alloc; + int nb_realloc; + int nb_free; + + size_t rem; + size_t max; + size_t tot; + +}; + +typedef struct +{ + size_t size; + + mmalloc_t* mm; + int id; + + double dummy; + +} mmheader_t; + +void* +octfapg_mm_malloc (size_t t) +{ + char* m = (char*)malloc(t+sizeof(mmheader_t)); + return m+sizeof(mmheader_t); +} + +oct_t* octfapg_empty (var_t n); + +oct_t* +octfapg_empty (const var_t n) +{ + oct_t* m; + /*octfapg_timing_enter("oct_empty",3);*/ + m = ((oct_t*) octfapg_mm_malloc (sizeof(oct_t))); + m->n = n; + m->ref = 1; + m->state = OCT_EMPTY; + m->closed = (oct_t*)((void *)0); + m->c = (num_t*)((void *)0); + /*octfapg_timing_exit("oct_empty",3);*/ + return m; +} + +oct_t* +octfapg_alloc (const var_t n) +{ + size_t nn = (2*(size_t)(n)*((size_t)(n)+1)); + oct_t* m; + m = octfapg_empty(n); + m->c = ((num_t*) octfapg_mm_malloc (sizeof(num_t)*(nn))); + ; + m->state = OCT_NORMAL; + m->closed = (oct_t*)((void *)0); + return m; +} + +oct_t* +octfapg_universe (const var_t n) +{ + oct_t* m; + size_t i, nn = (2*(size_t)(n)*((size_t)(n)+1)); + m = octfapg_alloc(n); + for (i=0;i<nn;i++) *(m->c+i) = num__infty; + for (i=0;i<2*n;i++) *(m->c+((size_t)(i)+(((size_t)(i)+1)*((size_t)(i)+1))/2)) = (num_t)(0); + m->state = OCT_CLOSED; + return m; +} + +int main (void) +{ + int i; + check_vect (); + + oct_t *p = octfapg_universe(10); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vector alignment may not be reachable" 1 "vect" { target { ! vector_alignment_reachable } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { ! vector_alignment_reachable } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr27151.c b/gcc/testsuite/gcc.dg/vect/pr27151.c new file mode 100644 index 000000000..81f89b1a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr27151.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +/* We were creating a float vector for the vis_type == 1 + test, which we ICEd on. Now we simply punt here. */ + +float vs_data[75]; +void vis_clear_data () +{ + int vis_type, i; + for (i = 0; i < 75; i++) + { + vs_data[i] = (vis_type == 1); + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr28952.c b/gcc/testsuite/gcc.dg/vect/pr28952.c new file mode 100644 index 000000000..7305e607c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr28952.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ + +/* We were ICE because we wanted to check the type of the + elements of a conditional before we knew it was a conditional. */ + +struct player_spaceship +{ + _Bool structure[32]; +}; +struct player +{ + struct player_spaceship spaceship; +}; +struct packet_spaceship_info +{ + char structure[32 + 1]; +}; +send_spaceship_info (void) +{ + int j; + struct player *pplayer; + struct packet_spaceship_info info; + struct player_spaceship *ship = &pplayer->spaceship; + for (j = 0; j < 32; j++) + { + info.structure[j] = ship->structure[j] ? '1' : '0'; + } + lsend_packet_spaceship_info (&info); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr30771.c b/gcc/testsuite/gcc.dg/vect/pr30771.c new file mode 100644 index 000000000..e9f4bd2ab --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr30771.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +int a[128]; + +int +main() +{ + short i; + + for (i=0; i<64; i++){ + a[i] = (int)i; + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr30784.c b/gcc/testsuite/gcc.dg/vect/pr30784.c new file mode 100644 index 000000000..3df9afe3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr30784.c @@ -0,0 +1,30 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +long stack_vars_sorted[32]; + +int +main1 (long n) +{ + long si; + + for (si = 0; si < n; ++si) + stack_vars_sorted[si] = si; +} + +int main () +{ + long si; + + check_vect (); + main1 (32); + + for (si = 0; si < 32; ++si) + if (stack_vars_sorted[si] != si) + abort (); + + return 0; +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr30795.c b/gcc/testsuite/gcc.dg/vect/pr30795.c new file mode 100644 index 000000000..53dc9fa51 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr30795.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +char bigDone[260]; +int runningOrder[260]; + +int +main() +{ + int i; + for (i = 0; i <= 255; i++) { + bigDone [i] = ((char)0); + runningOrder[i] = i; + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr30843.c b/gcc/testsuite/gcc.dg/vect/pr30843.c new file mode 100644 index 000000000..616b618f4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr30843.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_long } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +void dacP98FillRGBMap (unsigned char *pBuffer) +{ + unsigned long dw, dw1; + unsigned long *pdw = (unsigned long *)(pBuffer); + + for( dw = 256, dw1 = 0; dw; dw--, dw1 += 0x01010101) + { + *pdw++ = dw1; + *pdw++ = dw1; + *pdw++ = dw1; + *pdw++ = dw1; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr30858.c b/gcc/testsuite/gcc.dg/vect/pr30858.c new file mode 100644 index 000000000..0af2f8e9a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr30858.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +int +foo (int ko) +{ + int j,i; + for (j = 0; j < ko; j++) + i += (i > 10) ? -5 : 7; + return i; +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Unknown def-use cycle pattern." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr31041.c b/gcc/testsuite/gcc.dg/vect/pr31041.c new file mode 100644 index 000000000..361b358b8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr31041.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +struct UNewTrie +{ + int index[(0x110000 >> 1)]; +}; +typedef struct UNewTrie UNewTrie; +utrie_open_3_4 () +{ + UNewTrie *trie; + int i, j; + { + i = 0; + do + { + trie->index[i++] = j; + j += 1; + } + while (i < 5); + } +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr31343.c b/gcc/testsuite/gcc.dg/vect/pr31343.c new file mode 100644 index 000000000..856422221 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr31343.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ + +#define N 16 + +struct +{ + unsigned int x; + unsigned int y; +} pS [100]; + +void +main1 () +{ + int i, j; + unsigned int ub[N] = + { 1, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45 }; + unsigned int uc[N] = + { 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + unsigned int udiffx, udiffy; + + for (i = 0; i < N; i++) + { + pS[i].x = 0; + pS[i].y = 0; + for (j = 0; j < N; j++) + { + udiffx = (ub[j] - uc[j]); + udiffy = (ub[j] - uc[j]); + pS[i].x = udiffx; + pS[i].y = udiffy; + } + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr31699.c b/gcc/testsuite/gcc.dg/vect/pr31699.c new file mode 100644 index 000000000..6015d5cd4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr31699.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +float x[256]; + +__attribute__ ((noinline)) +double *foo(void) +{ + double *z = malloc (sizeof(double) * 256); + + int i; + for (i=0; i<256; ++i) + z[i] = x[i] + 1.0f; + + return z; +} + + +int main() +{ + int i; + + check_vect (); + + for (i = 0; i < 256; i++) + x[i] = (float) i; + + foo(); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_intfloat_cvt } } } */ +/* { dg-final { scan-tree-dump-times "vector alignment may not be reachable" 1 "vect" { target { ! vector_alignment_reachable } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { ! vector_alignment_reachable } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr32216.c b/gcc/testsuite/gcc.dg/vect/pr32216.c new file mode 100644 index 000000000..cf2744125 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr32216.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_floatint_cvt } */ + +unsigned int wlookup2[203]; + +SetSoundVariables (int x) +{ + for (x = 1; x < 32; x++) + { + wlookup2[x] = (double) 16 / x; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr32224.c b/gcc/testsuite/gcc.dg/vect/pr32224.c new file mode 100644 index 000000000..6f3a36b4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr32224.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +typedef unsigned long int *mp_ptr; +typedef const unsigned long int *mp_srcptr; +gmpz_export (void *data) +{ + mp_srcptr zp; + int count, i; + mp_ptr __dst = ((mp_ptr) data); + mp_srcptr __src = (zp); + + for (i = 0; i < count; i++) + { + __asm__ ("checkme": "=r" (*__dst):"0" (*(__src))); + __src++; + } +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr32230.c b/gcc/testsuite/gcc.dg/vect/pr32230.c new file mode 100644 index 000000000..bdb290ab4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr32230.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +typedef struct filter_buffer filter_buffer_t; +struct filter_buffer +{ + char buf[1]; +}; +typedef struct sbuf_header sbuf_header_t; +struct sbuf_header +{ + char buf[1]; +} +const_f (filter_buffer_t *buf) +{ + float val; + int i; + + for (i = 0; i < 10; i++) + ((float*) (&((sbuf_header_t *) (__PTRDIFF_TYPE__)((buf) == (filter_buffer_t *)&(buf)->buf[0]))->buf[0]))[i] = val; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/pr32366.c b/gcc/testsuite/gcc.dg/vect/pr32366.c new file mode 100644 index 000000000..e83d579e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr32366.c @@ -0,0 +1,14 @@ +/* Testcase by Martin Michlmayr <tbm@cyrius.com> */ + +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +stream_test (void) +{ + static float input[20]; + int k; + for (k = 0; k < 20; k++) + input[k] = k * 1.0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr32421.c b/gcc/testsuite/gcc.dg/vect/pr32421.c new file mode 100644 index 000000000..68d51bd74 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr32421.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + + +int f(int **__restrict a, int ** __restrict b) +{ + int i; + for(i= 0;i<32;i++) + a[i] = b[i] + 1; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr32824.c b/gcc/testsuite/gcc.dg/vect/pr32824.c new file mode 100644 index 000000000..8f36d1db2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr32824.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +int a[16*100]; +int e; +void foo(void) +{ + int i; + for(i = 0;i<16*100;i++) + e += a[i]; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr33369.c b/gcc/testsuite/gcc.dg/vect/pr33369.c new file mode 100644 index 000000000..1aaf4e366 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33369.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_shift } */ + +typedef struct tagPOINT +{ + int x; + int y; +} POINT; + +void +f (POINT * ptBuf) +{ + int i; + for (i = 0; i < 4; i++) + { + ptBuf[i].x = ((ptBuf[i].x) << 4); + ptBuf[i].y = ((ptBuf[i].y) << 4); + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33373.c b/gcc/testsuite/gcc.dg/vect/pr33373.c new file mode 100644 index 000000000..b11cfb4eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33373.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +void DOSMEM_FillIsrTable(int*isr) { + int i; + + for (i=0; i<256; i++) + isr[i]=(((short)((i*4) & 0xFFFF)) | (0xf000 & 0xFFFF) << 16); +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33373b.c b/gcc/testsuite/gcc.dg/vect/pr33373b.c new file mode 100644 index 000000000..c294a385c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33373b.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +void f (unsigned int *d, unsigned int *s, int w) +{ + int i; + for (i = 0; i < w; ++i) + d [i] = s [i] * (unsigned short) (~d [i] >> 24); +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33597.c b/gcc/testsuite/gcc.dg/vect/pr33597.c new file mode 100644 index 000000000..7fdcde07f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33597.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; + +void +rgb15to24_C (const uint8_t * src, uint8_t * dst, long src_size) +{ + const uint16_t *end; + const uint16_t *s = (uint16_t *)src; + uint8_t *d = (uint8_t *)dst; + + end = s + src_size/2; + while (s < end) + { + uint16_t bgr = *s++; + + *d++ = (bgr&0x1F)<<3; + *d++ = (bgr&0x3E0)>>2; + *d++ = (bgr&0x7C00)>>7; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33804.c b/gcc/testsuite/gcc.dg/vect/pr33804.c new file mode 100644 index 000000000..168213ee3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33804.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void f(unsigned char *s, unsigned char *d, int n) { + int i; + for (i = 0; i < n; i += 4) { + d[i + 0] += s[i + 0]; + d[i + 1] += s[i + 1]; + d[i + 2] += s[i + 2]; + d[i + 3] += s[i + 3]; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && ilp32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_align && ilp32 } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33833.c b/gcc/testsuite/gcc.dg/vect/pr33833.c new file mode 100644 index 000000000..ebdfcb1f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33833.c @@ -0,0 +1,35 @@ +/* Testcase by Martin Michlmayr <tbm@cyrius.com> */ +/* { dg-do compile } */ + +#define signed +typedef unsigned __PTRDIFF_TYPE__ uintptr_t; +#undef signed + +struct list_head +{ + struct list_head *prev; +}; +struct prio_array +{ + struct list_head queue[100]; +}; +struct rq +{ + struct prio_array *active, arrays[2]; +} per_cpu__runqueues; + +void sched_init (uintptr_t __ptr) +{ + int j, k; + struct prio_array *array; + struct rq *rq; + rq = (&(*( { (typeof (&per_cpu__runqueues)) (__ptr); } ))); + for (j = 0; j < 2; j++) + { + array = rq->arrays + j; + for (k = 0; k < 100; k++) + (array->queue + k)->prev = array->queue; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33846.c b/gcc/testsuite/gcc.dg/vect/pr33846.c new file mode 100644 index 000000000..3f421c9b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33846.c @@ -0,0 +1,24 @@ +/* Testcase by Martin Michlmayr <tbm@cyrius.com> */ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_shift } */ + +int clamp_val (int i) +{ + return ~i >> 31; +} + +typedef __PTRDIFF_TYPE__ intptr_t; + +void _mix_some_samples (intptr_t buf, int *mix_buffer, int mix_size) +{ + int i; + signed int *p = mix_buffer; + for (i = mix_size ; i > 0; i--) + { + *((short *) buf) = clamp_val ((*p) + 0x800000); + buf += 2; + p++; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr33866.c b/gcc/testsuite/gcc.dg/vect/pr33866.c new file mode 100644 index 000000000..9beaeff5b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33866.c @@ -0,0 +1,32 @@ +/* Testcase by Martin Michlmayr <tbm@cyrius.com> */ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_long } */ + +typedef struct +{ + long *coords; +} +fill_iter_info; + +extern H5Diterate (fill_iter_info *); + +void test_select_fill_hyper_simple (long *offset) +{ + long start[2]; + int num_points; + long points[16][2]; + fill_iter_info iter_info; + int i, j; + iter_info.coords = (long *) points; + for (i = 0, num_points = 0; j < (int) start[1]; j++, num_points++) + { + points[num_points][0] = i + start[0]; + points[num_points][1] = j + start[1]; + } + H5Diterate (&iter_info); +} + +/* Needs interleaving support. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr33953.c b/gcc/testsuite/gcc.dg/vect/pr33953.c new file mode 100644 index 000000000..f501a452e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr33953.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +typedef unsigned int UINT32; + +void blockmove_NtoN_blend_noremap32 (const UINT32 *srcdata, int srcwidth, + int srcheight, int srcmodulo, + UINT32 *dstdata, int dstmodulo, + int srcshift) +{ + UINT32 *end; + + while (srcheight) + { + while (dstdata <= end - 8) + { + dstdata[0] |= srcdata[0] << srcshift; + dstdata[1] |= srcdata[1] << srcshift; + dstdata[2] |= srcdata[2] << srcshift; + dstdata[3] |= srcdata[3] << srcshift; + dstdata[4] |= srcdata[4] << srcshift; + dstdata[5] |= srcdata[5] << srcshift; + dstdata[6] |= srcdata[6] << srcshift; + dstdata[7] |= srcdata[7] << srcshift; + dstdata += 8; + srcdata += 8; + } + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" {xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/pr34005.c b/gcc/testsuite/gcc.dg/vect/pr34005.c new file mode 100644 index 000000000..813f950b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr34005.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/34005 */ +/* { dg-do compile } */ + +/* Testcase by Martin Michlmayr <tbm@cyrius.com> */ + +void XdmcpUnwrap (unsigned char *output, int k) +{ + int i; + unsigned char blocks[2][8]; + k = (k == 0) ? 1 : 0; + for (i = 0; i < 32; i++) + output[i] = blocks[k][i]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr34407.c b/gcc/testsuite/gcc.dg/vect/pr34407.c new file mode 100644 index 000000000..3da2ed7b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr34407.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +extern int ReadBlobByte (void); + +void ReadRLEImage (unsigned char *p) +{ + unsigned char background_color[4] = { 0, 1, 2, 3 }; + long j; + + unsigned long number_planes = ReadBlobByte(); + + for (j = 0; j < (long) number_planes; j++) + *p++ = background_color[j]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr34591.c b/gcc/testsuite/gcc.dg/vect/pr34591.c new file mode 100644 index 000000000..1f02544c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr34591.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +int av_resample(int filter_length, short *src, short *filter) +{ + int i; + int val=0; + for(i=0; i<filter_length; i++) + val += src[ i ] * filter[i]; + return val; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr36228.c b/gcc/testsuite/gcc.dg/vect/pr36228.c new file mode 100644 index 000000000..73933754c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr36228.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-vect-details" } */ + +#define COLS 8 +#define ROWS 8 + +int +t_run_test(void); + +int +t_run_test() +{ + int k_1,i_1, j_1; + static signed char f_1[ROWS][COLS] ; + static long F_1[ROWS][COLS] ; + long cosMatrixA[ROWS][COLS] ; + + for( k_1 = 0 ; k_1 < COLS ; k_1++ ) + { + for( i_1 = 0 ; i_1 < ROWS ; i_1++ ) + { + for( j_1 = 0 ; j_1 < COLS ; j_1++ ) + F_1[i_1][j_1] += f_1[i_1][k_1] * cosMatrixA[k_1][j_1] ; + } + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "versioning for alias required" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr36493.c b/gcc/testsuite/gcc.dg/vect/pr36493.c new file mode 100644 index 000000000..98517dfc5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr36493.c @@ -0,0 +1,25 @@ +/* { dg-require-effective-target vect_long } */ + +#include "tree-vect.h" + +int +main (void) +{ + int i; + long x[12] __attribute__((aligned(__BIGGEST_ALIGNMENT__))); + + check_vect (); + + x[0] = 1; + for (i = 0; i < 12; i++) + x[i] = i; + + if (x[0] != 0) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr36630.c b/gcc/testsuite/gcc.dg/vect/pr36630.c new file mode 100644 index 000000000..2253f7574 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr36630.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void +foo (unsigned char *x, short y) +{ + short i; + + i = 2; + while (i < y) + { + x[i - 1] = x[i]; + i = i + 1; + } +} +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr37027.c b/gcc/testsuite/gcc.dg/vect/pr37027.c new file mode 100644 index 000000000..dcfed348d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37027.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> + +struct mystr +{ + int f1; + int f2; +}; + +struct mystr a[16]; +struct mystr b[16]; +int res1, res2; + + +void +foo (void) +{ + int i; + int sum1; + int sum2; + + for (i = 0; i < 16; i++) + { + sum1 += a[i].f1 + b[i].f1; + sum2 += a[i].f2 + b[i].f2; + } + + res1 = sum1; + res2 = sum2; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr37385.c b/gcc/testsuite/gcc.dg/vect/pr37385.c new file mode 100644 index 000000000..8b1cf3ae1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37385.c @@ -0,0 +1,20 @@ +/* Testcase by Martin Michlmayr <tbm@cyrius.com> */ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +typedef int int_t; +typedef void (*fun_t) (int); +fun_t fun_tab[400] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +void foo (int_t a); + +void +bar () +{ + int i; + + for (i = 0; i < 400; i++) + fun_tab[i] = foo; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr37474.c b/gcc/testsuite/gcc.dg/vect/pr37474.c new file mode 100644 index 000000000..b6d01c269 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37474.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> + +#define M00 100 +#define M10 216 +#define M01 1322 +#define M11 13 +#define M02 74 +#define M12 191 + +#define N 16 + +void foo (unsigned int *__restrict__ pInput, unsigned int *__restrict__ pOutput) +{ + unsigned int i, a, b, c, d, e, f; + + for (i = 0; i < N / 3; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + d = *pInput++; + e = *pInput++; + f = *pInput++; + + a = a + d; + b = b + e; + c = c + f; + + *pOutput++ = M00 * a + M01 * b + M02 * c; + *pOutput++ = M10 * a + M11 * b + M12 * c; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr37482.c b/gcc/testsuite/gcc.dg/vect/pr37482.c new file mode 100644 index 000000000..0b3bed33a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37482.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void SexiALI_Convert(void *vdest, void *vsrc, unsigned int frames) +{ + unsigned int x; + short *src = vsrc; + unsigned char *dest = vdest; + for(x=0;x<256;x++) + { + int tmp; + tmp = *src; + src++; + tmp += *src; + src++; + *dest++ = tmp; + *dest++ = tmp; + } +} +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr37539.c b/gcc/testsuite/gcc.dg/vect/pr37539.c new file mode 100644 index 000000000..1e73425de --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37539.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +__attribute__ ((noinline)) void +ayuv2yuyv_ref (int *d, int *src, int n) +{ + char *dest = (char *)d; + int i; + + for(i=0;i<n/2;i++){ + dest[i*4 + 0] = (src[i*2 + 0])>>16; + dest[i*4 + 1] = (src[i*2 + 1])>>8; + dest[i*4 + 2] = (src[i*2 + 0])>>16; + dest[i*4 + 3] = (src[i*2 + 0])>>0; + } + + /* Check results. */ + for(i=0;i<n/2;i++){ + if (dest[i*4 + 0] != (src[i*2 + 0])>>16 + || dest[i*4 + 1] != (src[i*2 + 1])>>8 + || dest[i*4 + 2] != (src[i*2 + 0])>>16 + || dest[i*4 + 3] != (src[i*2 + 0])>>0) + abort(); + } +} + +int main () +{ + int d[256], src[128], i; + + check_vect (); + + for (i = 0; i < 128; i++) + src[i] = i; + + ayuv2yuyv_ref(d, src, 128); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_strided_wide } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + + diff --git a/gcc/testsuite/gcc.dg/vect/pr37730.c b/gcc/testsuite/gcc.dg/vect/pr37730.c new file mode 100644 index 000000000..876f5499e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37730.c @@ -0,0 +1,16 @@ +/* PR middle-end/37730 */ +/* { dg-do compile } */ + +void +add_opush (void) +{ + unsigned char formats[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xff }; + void *dtds[sizeof (formats)]; + unsigned int i; + unsigned char dtd = 0x08; + for (i = 0; i < sizeof (formats); i++) + dtds[i] = &dtd; + sdp_seq_alloc (dtds); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr38529.c b/gcc/testsuite/gcc.dg/vect/pr38529.c new file mode 100644 index 000000000..496aa43f3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr38529.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +float a[4]; + +void foo() +{ + int i, j; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 17; ++j) + a[i] = 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/pr39529.c b/gcc/testsuite/gcc.dg/vect/pr39529.c new file mode 100644 index 000000000..4853c1350 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr39529.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +void +foo (void) +{ + char a[1024]; + char *p = &a[0]; + char *p2; + + p2 = p + 1024; + do + { + p += 2; + *(p-2) = 1; + *(p-1) = 1; + } while (p < p2); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/pr40074.c b/gcc/testsuite/gcc.dg/vect/pr40074.c new file mode 100644 index 000000000..6459f1b55 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr40074.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef struct { + int a; + int b; + int c; + int d; +} s; + + +s arr[N] = {{7,0,1,5}, {7,2,3,5}, {7,4,5,5}, {7,6,7,5}, {7,8,9,5}, {7,10,11,5}, {7,12,13,5}, {7,14,15,5}, {7,16,17,5}, {7,18,19,5}, {7,20,21,5}, {7,22,23,5}, {7,24,25,5}, {7,26,27,5}, {7,28,29,5}, {7,30,31,5}}; + +__attribute__ ((noinline)) int +main1 () +{ + s *p = arr, *q = arr + 1; + int res[N]; + int i; + + for (i = 0; i < N-1; i++) + { + res[i] = p->b + p->d + q->b; + p++; + q++; + } + + /* check results: */ + for (i = 0; i < N-1; i++) + { + if (res[i] != arr[i].b + arr[i].d + arr[i+1].b) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr40238.c b/gcc/testsuite/gcc.dg/vect/pr40238.c new file mode 100644 index 000000000..91cf09824 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr40238.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ + +extern int xdo_rb_ctr_row( int *pos_code); + +int xgp_ahd_interpolate (int tile) +{ + int p[4]; + + switch (tile) { + default: + case 0: + case 1: + p[0] = 0; p[1] = 1; p[2] = 2; p[3] = 3; + break; + case 2: + case 3: + p[0] = 1; p[1] = 0; p[2] = 3; p[3] = 2; + break; + case 4: + case 5: + p[0] = 3; p[1] = 2; p[2] = 1; p[3] = 0; + break; + case 6: + case 7: + p[0] = 2; p[1] = 3; p[2] = 0; p[3] = 1; + break; + } + + xdo_rb_ctr_row(p); + xdo_rb_ctr_row(p); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr40254.c b/gcc/testsuite/gcc.dg/vect/pr40254.c new file mode 100644 index 000000000..b890a4493 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr40254.c @@ -0,0 +1,39 @@ +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +struct s +{ + int *x; + int x1; + int x2; + int x3; + int *y; +}; + +struct s arr[64] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo (int i, int *in_x, int *in_y) +{ + arr[i].x = in_x; + arr[i].y = in_y; +} + +int +main (void) +{ + int a, b; + + check_vect (); + + foo (5, &a, &b); + + if (arr[5].x != &a || arr[5].y != &b) + abort (); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr40542.c b/gcc/testsuite/gcc.dg/vect/pr40542.c new file mode 100644 index 000000000..0a827724d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr40542.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ + +void +volarr_cpy(char *d, volatile char *s) +{ + int i; + + for (i = 0; i < 16; i++) + d[i] = s[i]; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr41956.c b/gcc/testsuite/gcc.dg/vect/pr41956.c new file mode 100644 index 000000000..455f50510 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr41956.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void K (int *gpwgts, int *badminpwgt, int *badmaxpwgt) +{ + int i; + for (i = 0; i < 10; i += 2) { + badminpwgt[i] = badminpwgt[i+1] = gpwgts[i]+gpwgts[i]; + badmaxpwgt[i] = badmaxpwgt[i+1] = gpwgts[i]+gpwgts[i]; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr42193.c b/gcc/testsuite/gcc.dg/vect/pr42193.c new file mode 100644 index 000000000..01609c982 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr42193.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_long } */ + +#include <stdarg.h> + +unsigned long in[6], out[6]; + +void foo () +{ + unsigned long a, b, c, d, e, f; + + a = in[0]; + b = in[1]; + c = in[2]; + d = in[3]; + e = in[4]; + f = in[5]; + + out[0] = 2 * a + 7 * b + 8 * c + 31 * d + 10 * e + 21 * f; + out[1] = 3 * a + 6 * b + 12 * c + 13 * d + 15 * e + 28 * f; + out[2] = 4 * a + 5 * b + 72 * c + 23 * d + 14 * e + 24 * f; + out[3] = 8 * a + 71 * b + 18 * c + 33 * d + 13 * e + 25 * f; + out[4] = 12 * a + 16 * b + 19 * c + 41 * d + 22 * e + 26 * f; + out[5] = 17 * a + 15 * b + 13 * c + 14 * d + 11 * e + 9 * f; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr42395.c b/gcc/testsuite/gcc.dg/vect/pr42395.c new file mode 100644 index 000000000..7d0b8324f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr42395.c @@ -0,0 +1,10 @@ +/* PR debug/42395 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -ftree-vectorize -g" } */ + +void foo(int j, int *A) +{ + int i; + for (i = 0; i < j; i ++) A[i] = i; + for (; i < 4096; i ++) A[i] = 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr42604.c b/gcc/testsuite/gcc.dg/vect/pr42604.c new file mode 100644 index 000000000..14f255a40 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr42604.c @@ -0,0 +1,35 @@ +/* PR debug/42604 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -ftree-vectorize -g -ffast-math" } */ + +unsigned *d; +unsigned short e; +int f; +float h[3][4]; + +void +test (unsigned short *b) +{ + int a, c, i; + float g[3]; + unsigned j[32] = { 10, 0x63707274 }; + for (i = 0; i < (int) j[0]; i++) + { + j[i * 3 + 2] = d[0]; + d[0] += (j[i * 3 + 3] + 3) & -4; + } + for (a = 0; a < e; a++) + { + g[0] = g[1] = g[2] = 0; + for (c = 0; c < f; c++) + { + g[0] += h[0][c] * b[c]; + g[1] += h[1][c] * b[c]; + } + for (c = 0; c < 3; c++) + b[c] = 0 > ((int) g[c] < 65535 ? ((int) g[c]) : 65535) + ? 0 : ((int) g[c]) < 65535 ? (int) g[c] : 65535; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr42709.c b/gcc/testsuite/gcc.dg/vect/pr42709.c new file mode 100644 index 000000000..8ccbfa65e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr42709.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int *res[N]; + +int +main1 (int *a, int *b, int *c, int *d, int dummy) +{ + int i; + + for (i = 0; i < N/2; i+=4) + { + res[i] = a + 16; + res[i+1] = b + 16; + res[i+2] = c + 16; + res[i+3] = d + 16; + if (dummy == 32) + abort (); + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr43430-1.c b/gcc/testsuite/gcc.dg/vect/pr43430-1.c new file mode 100644 index 000000000..9eaa23cca --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr43430-1.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef int myint; +myint data_ch1[N + 1] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }; +myint data_ch2[N + 1] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }; +#define SUM 480 + +__attribute__ ((noinline)) int +foo (myint * s1, myint * s2, int stride) +{ + int score = 0; + int x; + for (x = 0; x < N; x++) + score += ((s1[x] - s1[x + stride] + s2[x + stride]) >= 0 ? + s1[x] + s2[x + stride] : + s2[x + stride]); + + if (score != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (data_ch1, data_ch2, 1); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_condition } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr43430-2.c b/gcc/testsuite/gcc.dg/vect/pr43430-2.c new file mode 100644 index 000000000..16f53dacc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr43430-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +typedef unsigned char uint8_t; +vsad16_c (void *c, uint8_t * s1, uint8_t * s2, int stride, int h) +{ + int score = 0; + int x, y; + for (x = 0; x < 16; x++) + score += ((s1[x] - s1[x + stride] + s2[x + stride]) >= 0 ? + s1[x] + s2[x + stride] : + s2[x + stride]); + return score; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_condition } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr43432.c b/gcc/testsuite/gcc.dg/vect/pr43432.c new file mode 100644 index 000000000..5f3db7d82 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr43432.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + + +void vector_fmul_reverse_c(float *dst, const float *src0, const float *src1, +int len){ + int i; + src1 += len-1; + for(i=0; i<len; i++) + dst[i] = src0[i] * src1[-i]; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm && vect_hw_misalign } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr43842.c b/gcc/testsuite/gcc.dg/vect/pr43842.c new file mode 100644 index 000000000..593404ffb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr43842.c @@ -0,0 +1,55 @@ +/* { dg-do compile } */ + +typedef char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; + +static int16_t +safe_rshift_func_int16_t_s_u (int16_t left, unsigned int right) +{ + return left || right >= 1 * 8 ? left : left >> right; +} + +static int8_t +safe_rshift_func_int8_t_s_u (int8_t left, unsigned int right) +{ + return left || right >= 1 * 8 ? left : left >> right; +} + + +static uint32_t +safe_add_func_uint32_t_u_u (uint32_t ui1, uint16_t ui2) +{ + return ui1 + ui2; +} + +int16_t g_4; +int8_t g_4_8; +uint32_t g_9[1]; +uint32_t g_9_8[2]; +int161 (void) +{ + int32_t l_2; + + for (l_2 = -25; l_2; l_2 = safe_add_func_uint32_t_u_u (l_2, 1)) + g_9[0] ^= safe_rshift_func_int16_t_s_u (g_4, 1); +} + +int81 (void) +{ + int32_t l_2; + + for (l_2 = -25; l_2; l_2 = safe_add_func_uint32_t_u_u (l_2, 1)) + { + g_9[0] ^= safe_rshift_func_int8_t_s_u (g_4_8, 1); + g_9[1] ^= safe_rshift_func_int8_t_s_u (g_4_8, 1); + } + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr44507.c b/gcc/testsuite/gcc.dg/vect/pr44507.c new file mode 100644 index 000000000..50c485399 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr44507.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include "tree-vect.h" + +int seeIf256ByteArrayIsConstant( + unsigned char *pArray) +{ + int index; + unsigned int curVal, orVal, andVal; + int bytesAreEqual = 0; + + if (pArray != 0) + { + for (index = 0, orVal = 0, andVal = 0xFFFFFFFF; + index < 64; + index += (int)sizeof(unsigned int)) + { + curVal = *((unsigned int *)(&pArray[index])); + orVal = orVal | curVal; + andVal = andVal & curVal; + } + + if (!((orVal == andVal) + && ((orVal >> 8) == (andVal & 0x00FFFFFF)))) + abort (); + } + + return 0; +} + + +int main(int argc, char** argv) +{ + unsigned char array1[64] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + + argv = argv; + argc = argc; + + check_vect (); + + return seeIf256ByteArrayIsConstant(&array1[0]); +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr45633.c b/gcc/testsuite/gcc.dg/vect/pr45633.c new file mode 100644 index 000000000..456d51f1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr45633.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/45633 */ +/* { dg-do compile } */ + +int s[32]; +unsigned char *t[32]; + +void +foo (void) +{ + int i; + for (i = 0; i < 32; i++) + t[i] -= s[i]; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr45752.c b/gcc/testsuite/gcc.dg/vect/pr45752.c new file mode 100644 index 000000000..18047d525 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr45752.c @@ -0,0 +1,108 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M20 23 +#define M30 237 +#define M40 437 + +#define M01 1322 +#define M11 13 +#define M21 27271 +#define M31 2280 +#define M41 284 + +#define M02 74 +#define M12 191 +#define M22 500 +#define M32 111 +#define M42 1114 + +#define M03 134 +#define M13 117 +#define M23 11 +#define M33 771 +#define M43 71 + +#define M04 334 +#define M14 147 +#define M24 115 +#define M34 7716 +#define M44 16 + +#define N 16 + +void foo (unsigned int *__restrict__ pInput, + unsigned int *__restrict__ pOutput, + unsigned int *__restrict__ pInput2, + unsigned int *__restrict__ pOutput2) +{ + unsigned int i, a, b, c, d, e; + + for (i = 0; i < N / 5; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + d = *pInput++; + e = *pInput++; + + *pOutput++ = M00 * a + M01 * b + M02 * c + M03 * d + M04 * e; + *pOutput++ = M10 * a + M11 * b + M12 * c + M13 * d + M14 * e; + *pOutput++ = M20 * a + M21 * b + M22 * c + M23 * d + M24 * e; + *pOutput++ = M30 * a + M31 * b + M32 * c + M33 * d + M34 * e; + *pOutput++ = M40 * a + M41 * b + M42 * c + M43 * d + M44 * e; + + + a = *pInput2++; + b = *pInput2++; + c = *pInput2++; + d = *pInput2++; + e = *pInput2++; + + *pOutput2++ = M00 * a + M01 * b + M02 * c + M03 * d + M04 * e; + *pOutput2++ = M10 * a + M11 * b + M12 * c + M13 * d + M14 * e; + *pOutput2++ = M20 * a + M21 * b + M22 * c + M23 * d + M24 * e; + *pOutput2++ = M30 * a + M31 * b + M32 * c + M33 * d + M34 * e; + *pOutput2++ = M40 * a + M41 * b + M42 * c + M43 * d + M44 * e; + + } +} + +int main (int argc, const char* argv[]) +{ + unsigned int input[N], output[N], i, input2[N], output2[N]; + unsigned int check_results[N] = {3208, 1334, 28764, 35679, 2789, 13028, + 4754, 168364, 91254, 12399, 22848, 8174, 307964, 146829, 22009, 0}; + unsigned int check_results2[N] = {7136, 2702, 84604, 57909, 6633, 16956, + 6122, 224204, 113484, 16243, 26776, 9542, 363804, 169059, 25853, 0}; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + input2[i] = i + 2; + output[i] = 0; + output2[i] = 0; + __asm__ volatile (""); + } + + foo (input, output, input2, output2); + + for (i = 0; i < N; i++) + if (output[i] != check_results[i] + || output2[i] != check_results2[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 2 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr45847.c b/gcc/testsuite/gcc.dg/vect/pr45847.c new file mode 100644 index 000000000..f34caa1d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr45847.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + + +long long foo (long long *__restrict a, int *__restrict b, int *__restrict c ) +{ + int i; + long long sum=0; + for (i=0;i<256;i++) + sum += (long long)b[i] * c[i]; + + return sum; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr45902.c b/gcc/testsuite/gcc.dg/vect/pr45902.c new file mode 100644 index 000000000..1690b3ab3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr45902.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <stdlib.h> +#include "tree-vect.h" + +#define N 128 + +short res[N]; +short a[N]; + +int +main1 () +{ + int i; + + for (i = 0; i < N/4; i+=4) + { + res[i] = a[i] >> 8; + res[i+1] = a[i+1] >> 8; + res[i+2] = a[i+2] >> 8; + res[i+3] = a[i+3] >> 8; + } +} + +int +main () +{ + int i; + + for (i = 0; i < N; i++) + a[i] = i; + + main1 (); + + for (i = 0; i < N; i++) + if (res[i] != a[i] >> 8) + abort (); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr46009.c b/gcc/testsuite/gcc.dg/vect/pr46009.c new file mode 100644 index 000000000..a6a3217ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr46009.c @@ -0,0 +1,74 @@ +/* PR tree-optimization/46009 */ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +int a[1024] __attribute__((aligned)); +int b[1024] __attribute__((aligned)); +int c[1024] __attribute__((aligned)); +int d[1024] __attribute__((aligned)); +int e[1024] __attribute__((aligned)); + +void __attribute__((noinline)) +foo (void) +{ + int i, g; + for (i = 0; i < 1024; i++) + { + g = a[i] + b[i] + c[i] * d[i];; + e[i] = g < 10 ? 1 : g; + } +} + +void __attribute__((noinline)) +bar (void) +{ + int i, g; + for (i = 0; i < 1024; i++) + { + g = a[i] + b[i] + c[i] * d[i];; + if (g < 10) + e[i] = 1; + else + e[i] = g; + } +} + +int +main (void) +{ + int i; + check_vect (); + for (i = 0; i < 1024; i++) + { + asm volatile ("" : "+r" (i)); + a[i] = i % 10; + b[i] = i % 10; + c[i] = 1; + d[i] = -1; + e[i] = -1; + } + foo (); + for (i = 0; i < 1024; i++) + { + int g; + asm volatile ("" : "+r" (i)); + g = 2 * (i % 10) - 1; + if (e[i] != (g < 10 ? 1 : g)) + abort (); + e[i] = -1; + } + bar (); + for (i = 0; i < 1024; i++) + { + int g; + asm volatile ("" : "+r" (i)); + g = 2 * (i % 10) - 1; + if (e[i] != (g < 10 ? 1 : g)) + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr46049.c b/gcc/testsuite/gcc.dg/vect/pr46049.c new file mode 100644 index 000000000..90020681e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr46049.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ + +typedef __INT16_TYPE__ int16_t; +typedef __INT32_TYPE__ int32_t; + +static inline int32_t bar (int16_t x, int16_t y) +{ + return x * y; +} + +void foo (int16_t i, int16_t *p, int16_t x) +{ + while (i--) + { + *p = bar (*p, x) >> 15; + p++; + *p = bar (*p, x) >> 15; + p++; + } +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr46052.c b/gcc/testsuite/gcc.dg/vect/pr46052.c new file mode 100644 index 000000000..c32a93d07 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr46052.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ + +int i; +int a[2]; + +static inline char bar (void) +{ + return i ? i : 1; +} + +void foo (int n) +{ + while (n--) + { + a[0] ^= bar (); + a[1] ^= bar (); + } +} + +static inline char bar1 (void) +{ +} + +void foo1 (int n) +{ + while (n--) + { + a[0] ^= bar1 (); + a[1] ^= bar1 (); + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr46126.c b/gcc/testsuite/gcc.dg/vect/pr46126.c new file mode 100644 index 000000000..6eb178aab --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr46126.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ + +typedef struct TypHeader { + struct TypHeader * * ptr; + unsigned char type; + } * TypHandle; + extern TypHandle (* EvTab[81]) ( TypHandle hd ); + TypHandle FunApplyRel ( TypHandle hdCall ) + { + TypHandle hdApp; + TypHandle * ptApp; + long lp; + long lc; + hdApp = ((long)(((TypHandle*)((hdCall)->ptr))[1])&1 ? +(((TypHandle*)((hdCall)->ptr))[1]) : (* +EvTab[(((long)(((TypHandle*)((hdCall)->ptr))[1]) & 1) ? 1 : +((((TypHandle*)((hdCall)->ptr))[1])->type))])((((TypHandle*)((hdCall)->ptr))[1]))); + ptApp = ((TypHandle*)((hdApp)->ptr)); + ptApp[1] = ((TypHandle) (((long)(lp) << 2) + 1)); + ptApp[2] = ((TypHandle) (((long)(lc) << 2) + 1)); + } + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr46663.c b/gcc/testsuite/gcc.dg/vect/pr46663.c new file mode 100644 index 000000000..42a1ffbbc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr46663.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O -ftree-vectorize -fdump-tree-vect-details -fexceptions" } */ + +typedef __attribute__ ((const)) int (*bart) (void); + +int foo (bart bar, int m) +{ + int i, j = 0; + for (i = 0; i < m; i++) + j += bar(); + return j; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr47001.c b/gcc/testsuite/gcc.dg/vect/pr47001.c new file mode 100644 index 000000000..9c5d08dac --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr47001.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +#include <stdlib.h> + +#define N 128 + +int a[N]; + +int main1 (int res0, int res1) +{ + int i; + int sum0 = 0, sum1 = 0; + + for (i = 0; i < N/2; i++) { + sum1 += a[2*i]; + sum0 += a[2*i]; + } + + /* Check results: */ + if (sum0 != res0 + || sum1 != res1) + abort (); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr47139.c b/gcc/testsuite/gcc.dg/vect/pr47139.c new file mode 100644 index 000000000..9e9c751e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr47139.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +int d; + +void +foo () +{ + int a = 0; + unsigned char b; + for (b = 1; b; b++) + { + d = a; + a |= b; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/pr48172.c b/gcc/testsuite/gcc.dg/vect/pr48172.c new file mode 100644 index 000000000..892aecaf8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr48172.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ + +extern void *memset(void *s, int c, __SIZE_TYPE__ n); +extern void abort (void); + +#define ASIZE 1028 +#define HALF (ASIZE/2) + +int main() { + unsigned int array[ASIZE]; + int i; + + memset(array, 0, sizeof(array)); + + /* initialize first half of the array */ + for (i = 0; i < HALF; i++) + array[i] = i; + + /* fill second half of array in by summing earlier elements of the array + gcc 4.5.1 and 4.5.2 incorrectly vectorize this loop! aray[1025] is left + at 0 for ASIZE=1028 */ + for (i = 0; i < HALF-1; i++) + array[HALF+i] = array[2*i] + array[2*i + 1]; + + /* see if we have any failures */ + for (i = 0; i < HALF - 1; i++) + if (array[HALF+i] != array[2*i] + array[2*i + 1]) + abort (); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr48377.c b/gcc/testsuite/gcc.dg/vect/pr48377.c new file mode 100644 index 000000000..86d353165 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr48377.c @@ -0,0 +1,26 @@ +/* PR tree-optimization/48377 */ +/* { dg-do run } */ +/* { dg-require-effective-target non_strict_align } */ + +typedef unsigned int U __attribute__((__aligned__ (1), __may_alias__)); + +__attribute__((noinline, noclone)) unsigned int +foo (const char *s, int len) +{ + const U *p = (const U *) s; + unsigned int f = len / sizeof (unsigned int), hash = len, i; + + for (i = 0; i < f; ++i) + hash += *p++; + return hash; +} + +char buf[64] __attribute__((aligned (32))); + +int +main (void) +{ + return foo (buf + 1, 26) != 26; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr49038.c b/gcc/testsuite/gcc.dg/vect/pr49038.c new file mode 100644 index 000000000..91c214ffd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr49038.c @@ -0,0 +1,42 @@ +#include <sys/mman.h> +#include <stdio.h> + +#define COUNT 320 +#define MMAP_SIZE 0x10000 +#define ADDRESS 0x1122000000 +#define TYPE unsigned short + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +void __attribute__((noinline)) +foo (TYPE *__restrict a, TYPE *__restrict b) +{ + int n; + + for (n = 0; n < COUNT; n++) + a[n] = b[n * 2]; +} + +int +main (void) +{ + void *x; + size_t b_offset; + + x = mmap ((void *) ADDRESS, MMAP_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (x == MAP_FAILED) + { + perror ("mmap"); + return 1; + } + + b_offset = MMAP_SIZE - (2 * COUNT - 1) * sizeof (TYPE); + foo ((unsigned short *) x, + (unsigned short *) ((char *) x + b_offset)); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr49093.c b/gcc/testsuite/gcc.dg/vect/pr49093.c new file mode 100644 index 000000000..b8bded686 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr49093.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -ftree-vectorize -fdump-tree-vect-details -fno-tree-fre" } */ + +volatile unsigned char g_324[4] = {0, 1, 0, 1}; +void foo (int); +int x, y; +void func_81(void) +{ + int l_466, l_439[7] = {0}, g_97; +lbl_473: + if (x) { + for (g_97 = 0; (g_97 < 4); ++g_97) { + if (y) + goto lbl_473; + g_324[g_97]; + l_466 = l_439[g_97]; + } + foo(l_466); + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/section-anchors-pr27770.c b/gcc/testsuite/gcc.dg/vect/section-anchors-pr27770.c new file mode 100644 index 000000000..7513d93a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/section-anchors-pr27770.c @@ -0,0 +1,31 @@ +/* { dg-require-effective-target section_anchors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +short x; +static short f[100] = {0}; +int +bar (void) +{ + return f[0]; +} +void +foo (void) +{ + int i; + for (i = 0; i < 100; i++) + f[i]++; +} +int main (void) +{ + int i; + check_vect (); + foo (); + for (i = 0; i < 100; i++) + if (f[i]!=1) + abort (); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/section-anchors-vect-69.c b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-69.c new file mode 100644 index 000000000..7b5ce7348 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-69.c @@ -0,0 +1,120 @@ +/* { dg-require-effective-target section_anchors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct s2{ + int m; + int n[N-1][N-1][N-1]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +struct test2{ + struct s2 a; /* array a.n is unaligned */ + int b; + int c; + struct s2 e; /* array e.n is aligned */ +}; + + +struct test1 tmp1[4]; +struct test2 tmp2[4]; + +int main1 () +{ + int i,j; + + /* 1. unaligned */ + for (i = 0; i < N; i++) + { + tmp1[2].a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1[2].a.n[1][2][i] != 5) + abort (); + } + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1[2].a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1[2].a.n[1][2][i] != 6) + abort (); + } + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + tmp1[2].e.n[1][i][j] = 8; + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (tmp1[2].e.n[1][i][j] != 8) + abort (); + } + } + + /* 4. unaligned */ + for (i = 0; i < N-4; i++) + { + for (j = 0; j < N-4; j++) + { + tmp2[2].e.n[1][i][j] = 8; + } + } + + /* check results: */ + for (i = 0; i < N-4; i++) + { + for (j = 0; j < N-4; j++) + { + if (tmp2[2].e.n[1][i][j] != 8) + abort (); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_int } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* Alignment forced using versioning until the pass that increases alignment + is extended to handle structs. */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 4 "vect" { target {vect_int && vector_alignment_reachable } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 4 "vect" { target {vect_int && {! vector_alignment_reachable} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-1.c b/gcc/testsuite/gcc.dg/vect/slp-1.c new file mode 100644 index 000000000..6e95b6166 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-1.c @@ -0,0 +1,123 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int +main1 () +{ + int i; + unsigned short out[N*8]; + + for (i = 0; i < N; i++) + { + out[i*4] = 8; + out[i*4 + 1] = 18; + out[i*4 + 2] = 28; + out[i*4 + 3] = 38; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != 8 + || out[i*4 + 1] != 18 + || out[i*4 + 2] != 28 + || out[i*4 + 3] != 38) + abort (); + } + + for (i = 0; i < N; i++) + { + out[i*8] = 8; + out[i*8 + 1] = 7; + out[i*8 + 2] = 81; + out[i*8 + 3] = 28; + out[i*8 + 4] = 18; + out[i*8 + 5] = 85; + out[i*8 + 6] = 5; + out[i*8 + 7] = 4; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != 8 + || out[i*8 + 1] != 7 + || out[i*8 + 2] != 81 + || out[i*8 + 3] != 28 + || out[i*8 + 4] != 18 + || out[i*8 + 5] != 85 + || out[i*8 + 6] != 5 + || out[i*8 + 7] != 4) + abort (); + } + + /* SLP with unrolling by 8. */ + for (i = 0; i < N; i++) + { + out[i*5] = 8; + out[i*5 + 1] = 7; + out[i*5 + 2] = 81; + out[i*5 + 3] = 28; + out[i*5 + 4] = 18; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*5] != 8 + || out[i*5 + 1] != 7 + || out[i*5 + 2] != 81 + || out[i*5 + 3] != 28 + || out[i*5 + 4] != 18) + abort (); + } + + /* SLP with unrolling by 8. */ + for (i = 0; i < N/2; i++) + { + out[i*9] = 8; + out[i*9 + 1] = 7; + out[i*9 + 2] = 81; + out[i*9 + 3] = 28; + out[i*9 + 4] = 18; + out[i*9 + 5] = 85; + out[i*9 + 6] = 5; + out[i*9 + 7] = 4; + out[i*9 + 8] = 14; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*9] != 8 + || out[i*9 + 1] != 7 + || out[i*9 + 2] != 81 + || out[i*9 + 3] != 28 + || out[i*9 + 4] != 18 + || out[i*9 + 5] != 85 + || out[i*9 + 6] != 5 + || out[i*9 + 7] != 4 + || out[i*9 + 8] != 14) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-10.c b/gcc/testsuite/gcc.dg/vect/slp-10.c new file mode 100644 index 000000000..16a0c257d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-10.c @@ -0,0 +1,113 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + float out2[N*8]; + + for (i = 0; i < N; i++) + { + + a0 = in[i*8] + 5; + a1 = in[i*8 + 1] + 6; + a2 = in[i*8 + 2] + 7; + a3 = in[i*8 + 3] + 8; + a4 = in[i*8 + 4] + 9; + a5 = in[i*8 + 5] + 10; + a6 = in[i*8 + 6] + 11; + a7 = in[i*8 + 7] + 12; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + b7 = a7 * 2; + + out[i*8] = b0 - 2; + out[i*8 + 1] = b1 - 3; + out[i*8 + 2] = b2 - 2; + out[i*8 + 3] = b3 - 1; + out[i*8 + 4] = b4 - 8; + out[i*8 + 5] = b5 - 7; + out[i*8 + 6] = b6 - 3; + out[i*8 + 7] = b7 - 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (in[i*8] + 5) * 3 - 2 + || out[i*8 + 1] != (in[i*8 + 1] + 6) * 2 - 3 + || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 + || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 + || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 + || out[i*8 + 5] != (in[i*8 + 5] + 10) * 4 - 7 + || out[i*8 + 6] != (in[i*8 + 6] + 11) * 3 - 3 + || out[i*8 + 7] != (in[i*8 + 7] + 12) * 2 - 7) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = (in[i*4] + 2) * 3; + out[i*4 + 1] = (in[i*4 + 1] + 2) * 7; + out[i*4 + 2] = (in[i*4 + 2] + 7) * 3; + out[i*4 + 3] = (in[i*4 + 3] + 7) * 7; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != (in[i*4] + 2) * 3 + || out[i*4 + 1] != (in[i*4 + 1] + 2) * 7 + || out[i*4 + 2] != (in[i*4 + 2] + 7) * 3 + || out[i*4 + 3] != (in[i*4 + 3] + 7) * 7) + abort (); + } + + for (i = 0; i < N*4; i++) + { + out2[i*2] = (float) (in[i*2] * 2 + 5) ; + out2[i*2 + 1] = (float) (in[i*2 + 1] * 3 + 7); + } + + /* check results: */ + for (i = 0; i < N*4; i++) + { + if (out2[i*2] != (float) (in[i*2] * 2 + 5) + || out2[i*2 + 1] != (float) (in[i*2 + 1] * 3 + 7)) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {target {vect_uintfloat_cvt && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {target {{! { vect_uintfloat_cvt}} && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" {target {{! { vect_uintfloat_cvt}} && { ! {vect_int_mult}}} } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" {target {vect_uintfloat_cvt && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" {target {{! { vect_uintfloat_cvt}} && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" {target {{! { vect_uintfloat_cvt}} && { ! {vect_int_mult}}} } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-11.c b/gcc/testsuite/gcc.dg/vect/slp-11.c new file mode 100644 index 000000000..9f44e517e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-11.c @@ -0,0 +1,113 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + float out2[N*8]; + + /* Different operations - not SLPable. */ + for (i = 0; i < N; i++) + { + a0 = in[i*8] + 5; + a1 = in[i*8 + 1] * 6; + a2 = in[i*8 + 2] + 7; + a3 = in[i*8 + 3] + 8; + a4 = in[i*8 + 4] + 9; + a5 = in[i*8 + 5] + 10; + a6 = in[i*8 + 6] + 11; + a7 = in[i*8 + 7] + 12; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + b7 = a7 * 2; + + out[i*8] = b0 - 2; + out[i*8 + 1] = b1 - 3; + out[i*8 + 2] = b2 - 2; + out[i*8 + 3] = b3 - 1; + out[i*8 + 4] = b4 - 8; + out[i*8 + 5] = b5 - 7; + out[i*8 + 6] = b6 - 3; + out[i*8 + 7] = b7 - 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (in[i*8] + 5) * 3 - 2 + || out[i*8 + 1] != (in[i*8 + 1] * 6) * 2 - 3 + || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 + || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 + || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 + || out[i*8 + 5] != (in[i*8 + 5] + 10) * 4 - 7 + || out[i*8 + 6] != (in[i*8 + 6] + 11) * 3 - 3 + || out[i*8 + 7] != (in[i*8 + 7] + 12) * 2 - 7) + abort (); + } + + /* Requires permutation - not SLPable. */ + for (i = 0; i < N*2; i++) + { + out[i*4] = (in[i*4] + 2) * 3; + out[i*4 + 1] = (in[i*4 + 2] + 2) * 7; + out[i*4 + 2] = (in[i*4 + 1] + 7) * 3; + out[i*4 + 3] = (in[i*4 + 3] + 3) * 4; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != (in[i*4] + 2) * 3 + || out[i*4 + 1] != (in[i*4 + 2] + 2) * 7 + || out[i*4 + 2] != (in[i*4 + 1] + 7) * 3 + || out[i*4 + 3] != (in[i*4 + 3] + 3) * 4) + abort (); + } + + /* Different operations - not SLPable. */ + for (i = 0; i < N*4; i++) + { + out2[i*2] = ((float) in[i*2] * 2 + 6) ; + out2[i*2 + 1] = (float) (in[i*2 + 1] * 3 + 7); + } + + /* check results: */ + for (i = 0; i < N*4; i++) + { + if (out2[i*2] != ((float) in[i*2] * 2 + 6) + || out2[i*2 + 1] != (float) (in[i*2 + 1] * 3 + 7)) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { { vect_uintfloat_cvt && vect_strided_wide } && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { { { ! vect_uintfloat_cvt } && vect_strided_wide } && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" {target { ! { vect_int_mult && vect_strided_wide } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-12a.c b/gcc/testsuite/gcc.dg/vect/slp-12a.c new file mode 100644 index 000000000..6bbeb879f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-12a.c @@ -0,0 +1,104 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + unsigned int ia[N], ib[N*2]; + + for (i = 0; i < N; i++) + { + + a0 = in[i*8] + 5; + a1 = in[i*8 + 1] + 6; + a2 = in[i*8 + 2] + 7; + a3 = in[i*8 + 3] + 8; + a4 = in[i*8 + 4] + 9; + a5 = in[i*8 + 5] + 10; + a6 = in[i*8 + 6] + 11; + a7 = in[i*8 + 7] + 12; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + b7 = a7 * 2; + + out[i*8] = b0 - 2; + out[i*8 + 1] = b1 - 3; + out[i*8 + 2] = b2 - 2; + out[i*8 + 3] = b3 - 1; + out[i*8 + 4] = b4 - 8; + out[i*8 + 5] = b5 - 7; + out[i*8 + 6] = b6 - 3; + out[i*8 + 7] = b7 - 7; + + ia[i] = b6; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (in[i*8] + 5) * 3 - 2 + || out[i*8 + 1] != (in[i*8 + 1] + 6) * 2 - 3 + || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 + || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 + || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 + || out[i*8 + 5] != (in[i*8 + 5] + 10) * 4 - 7 + || out[i*8 + 6] != (in[i*8 + 6] + 11) * 3 - 3 + || out[i*8 + 7] != (in[i*8 + 7] + 12) * 2 - 7 + || ia[i] != (in[i*8 + 6] + 11) * 3) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = (in[i*4] + 2) * 3; + out[i*4 + 1] = (in[i*4 + 1] + 2) * 7; + out[i*4 + 2] = (in[i*4 + 2] + 7) * 3; + out[i*4 + 3] = (in[i*4 + 3] + 7) * 7; + + ib[i] = 7; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != (in[i*4] + 2) * 3 + || out[i*4 + 1] != (in[i*4 + 1] + 2) * 7 + || out[i*4 + 2] != (in[i*4 + 2] + 7) * 3 + || out[i*4 + 3] != (in[i*4 + 3] + 7) * 7 + || ib[i] != 7) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {target { vect_strided_wide && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {target { {! {vect_strided_wide}} && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" {target { ! vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" {target { vect_strided_wide && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" {target { {! {vect_strided_wide}} && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" {target { ! vect_int_mult } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-12b.c b/gcc/testsuite/gcc.dg/vect/slp-12b.c new file mode 100644 index 000000000..863652a5b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-12b.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_uintfloat_cvt } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +int +main1 () +{ + int i; + float out2[N*8], fa[N*4]; + + for (i = 0; i < N; i++) + { + out2[i*2] = (float) (in[i*2] * 2 + 11) ; + out2[i*2 + 1] = (float) (in[i*2 + 1] * 3 + 7); + + fa[i] = (float) in[i*2+1]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out2[i*2] != (float) (in[i*2] * 2 + 11) + || out2[i*2 + 1] != (float) (in[i*2 + 1] * 3 + 7) + || fa[i] != (float) in[i*2+1]) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {target { vect_strided_wide && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" {target { { ! { vect_int_mult }} || { ! {vect_strided_wide}}} } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" {target { vect_strided_wide && vect_int_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" {target { { ! { vect_int_mult }} || { ! {vect_strided_wide}}} } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-13.c b/gcc/testsuite/gcc.dg/vect/slp-13.c new file mode 100644 index 000000000..655e6ade1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-13.c @@ -0,0 +1,133 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned short out[N*8]; + unsigned short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + unsigned int in2[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + unsigned int out2[N*8]; + + /* Induction is not SLPable yet. */ + for (i = 0; i < N; i++) + { + out[i*8] = in[i*8] + i; + out[i*8 + 1] = in[i*8 + 1] + i; + out[i*8 + 2] = in[i*8 + 2] + i; + out[i*8 + 3] = in[i*8 + 3] + i; + out[i*8 + 4] = in[i*8 + 4] + i; + out[i*8 + 5] = in[i*8 + 5] + i; + out[i*8 + 6] = in[i*8 + 6] + i; + out[i*8 + 7] = in[i*8 + 7] + i; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + i + || out[i*8 + 1] != in[i*8 + 1] + i + || out[i*8 + 2] != in[i*8 + 2] + i + || out[i*8 + 3] != in[i*8 + 3] + i + || out[i*8 + 4] != in[i*8 + 4] + i + || out[i*8 + 5] != in[i*8 + 5] + i + || out[i*8 + 6] != in[i*8 + 6] + i + || out[i*8 + 7] != in[i*8 + 7] + i) + abort (); + } + + /* Induction is not SLPable yet and strided group size must be a power of 2 + to get vectorized. */ + for (i = 0; i < N/2; i++) + { + out2[i*12] = in2[i*12] + i; + out2[i*12 + 1] = in2[i*12 + 1] + i; + out2[i*12 + 2] = in2[i*12 + 2] + i; + out2[i*12 + 3] = in2[i*12 + 3] + i; + out2[i*12 + 4] = in2[i*12 + 4] + i; + out2[i*12 + 5] = in2[i*12 + 5] + i; + out2[i*12 + 6] = in2[i*12 + 6] + i; + out2[i*12 + 7] = in2[i*12 + 7] + i; + out2[i*12 + 8] = in2[i*12 + 8] + i; + out2[i*12 + 9] = in2[i*12 + 9] + i; + out2[i*12 + 10] = in2[i*12 + 10] + i; + out2[i*12 + 11] = in2[i*12 + 11] + i; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out2[i*12] != in2[i*12] + i + || out2[i*12 + 1] != in2[i*12 + 1] + i + || out2[i*12 + 2] != in2[i*12 + 2] + i + || out2[i*12 + 3] != in2[i*12 + 3] + i + || out2[i*12 + 4] != in2[i*12 + 4] + i + || out2[i*12 + 5] != in2[i*12 + 5] + i + || out2[i*12 + 6] != in2[i*12 + 6] + i + || out2[i*12 + 7] != in2[i*12 + 7] + i + || out2[i*12 + 8] != in2[i*12 + 8] + i + || out2[i*12 + 9] != in2[i*12 + 9] + i + || out2[i*12 + 10] != in2[i*12 + 10] + i + || out2[i*12 + 11] != in2[i*12 + 11] + i) + abort (); + } + + /* Not power of 2 but SLPable. */ + for (i = 0; i < N/2; i++) + { + out2[i*12] = in2[i*12] + 1; + out2[i*12 + 1] = in2[i*12 + 1] + 2; + out2[i*12 + 2] = in2[i*12 + 2] + 3; + out2[i*12 + 3] = in2[i*12 + 3] + 4; + out2[i*12 + 4] = in2[i*12 + 4] + 5; + out2[i*12 + 5] = in2[i*12 + 5] + 6; + out2[i*12 + 6] = in2[i*12 + 6] + 7; + out2[i*12 + 7] = in2[i*12 + 7] + 8; + out2[i*12 + 8] = in2[i*12 + 8] + 9; + out2[i*12 + 9] = in2[i*12 + 9] + 10; + out2[i*12 + 10] = in2[i*12 + 10] + 11; + out2[i*12 + 11] = in2[i*12 + 11] + 12; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out2[i*12] != in2[i*12] + 1 + || out2[i*12 + 1] != in2[i*12 + 1] + 2 + || out2[i*12 + 2] != in2[i*12 + 2] + 3 + || out2[i*12 + 3] != in2[i*12 + 3] + 4 + || out2[i*12 + 4] != in2[i*12 + 4] + 5 + || out2[i*12 + 5] != in2[i*12 + 5] + 6 + || out2[i*12 + 6] != in2[i*12 + 6] + 7 + || out2[i*12 + 7] != in2[i*12 + 7] + 8 + || out2[i*12 + 8] != in2[i*12 + 8] + 9 + || out2[i*12 + 9] != in2[i*12 + 9] + 10 + || out2[i*12 + 10] != in2[i*12 + 10] + 11 + || out2[i*12 + 11] != in2[i*12 + 11] + 12) + abort (); + } + + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-14.c b/gcc/testsuite/gcc.dg/vect/slp-14.c new file mode 100644 index 000000000..9e0746b9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-14.c @@ -0,0 +1,116 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned short in2[N*16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +int +main1 (int n) +{ + int i; + unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + unsigned short out2[N*16]; + + /* Multiple types are now SLPable. */ + for (i = 0; i < n; i++) + { + a0 = in[i*8] + 5; + a1 = in[i*8 + 1] + 6; + a2 = in[i*8 + 2] + 7; + a3 = in[i*8 + 3] + 8; + a4 = in[i*8 + 4] + 9; + a5 = in[i*8 + 5] + 10; + a6 = in[i*8 + 6] + 11; + a7 = in[i*8 + 7] + 12; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + b7 = a7 * 2; + + out[i*8] = b0 - 2; + out[i*8 + 1] = b1 - 3; + out[i*8 + 2] = b2 - 2; + out[i*8 + 3] = b3 - 1; + out[i*8 + 4] = b4 - 8; + out[i*8 + 5] = b5 - 7; + out[i*8 + 6] = b6 - 3; + out[i*8 + 7] = b7 - 7; + + out2[i*16] = in2[i*16] + 2; + out2[i*16 + 1] = in2[i*16 + 1] + 3; + out2[i*16 + 2] = in2[i*16 + 2] + 4; + out2[i*16 + 3] = in2[i*16 + 3] + 3; + out2[i*16 + 4] = in2[i*16 + 4] + 2; + out2[i*16 + 5] = in2[i*16 + 5] + 3; + out2[i*16 + 6] = in2[i*16 + 6] + 2; + out2[i*16 + 7] = in2[i*16 + 7] + 4; + out2[i*16 + 8] = in2[i*16 + 8] + 2; + out2[i*16 + 9] = in2[i*16 + 9] + 5; + out2[i*16 + 10] = in2[i*16 + 10] + 2; + out2[i*16 + 11] = in2[i*16 + 11] + 3; + out2[i*16 + 12] = in2[i*16 + 12] + 4; + out2[i*16 + 13] = in2[i*16 + 13] + 4; + out2[i*16 + 14] = in2[i*16 + 14] + 3; + out2[i*16 + 15] = in2[i*16 + 15] + 2; +} + + /* check results: */ + for (i = 0; i < n; i++) + { + if (out[i*8] != (in[i*8] + 5) * 3 - 2 + || out[i*8 + 1] != (in[i*8 + 1] + 6) * 2 - 3 + || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 + || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 + || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 + || out[i*8 + 5] != (in[i*8 + 5] + 10) * 4 - 7 + || out[i*8 + 6] != (in[i*8 + 6] + 11) * 3 - 3 + || out[i*8 + 7] != (in[i*8 + 7] + 12) * 2 - 7) + abort (); + + if (out2[i*16] != in2[i*16] + 2 + || out2[i*16 + 1] != in2[i*16 + 1] + 3 + || out2[i*16 + 2] != in2[i*16 + 2] + 4 + || out2[i*16 + 3] != in2[i*16 + 3] + 3 + || out2[i*16 + 4] != in2[i*16 + 4] + 2 + || out2[i*16 + 5] != in2[i*16 + 5] + 3 + || out2[i*16 + 6] != in2[i*16 + 6] + 2 + || out2[i*16 + 7] != in2[i*16 + 7] + 4 + || out2[i*16 + 8] != in2[i*16 + 8] + 2 + || out2[i*16 + 9] != in2[i*16 + 9] + 5 + || out2[i*16 + 10] != in2[i*16 + 10] + 2 + || out2[i*16 + 11] != in2[i*16 + 11] + 3 + || out2[i*16 + 12] != in2[i*16 + 12] + 4 + || out2[i*16 + 13] != in2[i*16 + 13] + 4 + || out2[i*16 + 14] != in2[i*16 + 14] + 3 + || out2[i*16 + 15] != in2[i*16 + 15] + 2) + abort (); + + } + + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-15.c b/gcc/testsuite/gcc.dg/vect/slp-15.c new file mode 100644 index 000000000..898538a3d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-15.c @@ -0,0 +1,118 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned int in2[N*16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned int out2[N*16]; + +int +main1 (int n) +{ + int i; + unsigned int a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + + for (i = 0; i < n; i++) + { + a0 = in[i*8] + 5; + a1 = in[i*8 + 1] + 6; + a2 = in[i*8 + 2] + 7; + a3 = in[i*8 + 3] + 8; + a4 = in[i*8 + 4] + 9; + a5 = in[i*8 + 5] + 10; + a6 = in[i*8 + 6] + 11; + a7 = in[i*8 + 7] + 12; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + b7 = a7 * 2; + + out[i*8] = b0 - 2; + out[i*8 + 1] = b1 - 3; + out[i*8 + 2] = b2 - 2; + out[i*8 + 3] = b3 - 1; + out[i*8 + 4] = b4 - 8; + out[i*8 + 5] = b5 - 7; + out[i*8 + 6] = b6 - 3; + out[i*8 + 7] = b7 - 7; + + out2[i*16] = in2[i*16] * 2; + out2[i*16 + 1] = in2[i*16 + 1] * 3; + out2[i*16 + 2] = in2[i*16 + 2] * 4; + out2[i*16 + 3] = in2[i*16 + 3] * 3; + out2[i*16 + 4] = in2[i*16 + 4] * 2; + out2[i*16 + 5] = in2[i*16 + 5] * 3; + out2[i*16 + 6] = in2[i*16 + 6] * 2; + out2[i*16 + 7] = in2[i*16 + 7] * 4; + out2[i*16 + 8] = in2[i*16 + 8] * 2; + out2[i*16 + 9] = in2[i*16 + 9] * 5; + out2[i*16 + 10] = in2[i*16 + 10] * 2; + out2[i*16 + 11] = in2[i*16 + 11] * 3; + out2[i*16 + 12] = in2[i*16 + 12] * 4; + out2[i*16 + 13] = in2[i*16 + 13] * 4; + out2[i*16 + 14] = in2[i*16 + 14] * 3; + out2[i*16 + 15] = in2[i*16 + 15] * 2; +} + + /* check results: */ + for (i = 0; i < n; i++) + { + if (out[i*8] != (in[i*8] + 5) * 3 - 2 + || out[i*8 + 1] != (in[i*8 + 1] + 6) * 2 - 3 + || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 + || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 + || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 + || out[i*8 + 5] != (in[i*8 + 5] + 10) * 4 - 7 + || out[i*8 + 6] != (in[i*8 + 6] + 11) * 3 - 3 + || out[i*8 + 7] != (in[i*8 + 7] + 12) * 2 - 7) + abort (); + + if (out2[i*16] != in2[i*16] * 2 + || out2[i*16 + 1] != in2[i*16 + 1] * 3 + || out2[i*16 + 2] != in2[i*16 + 2] * 4 + || out2[i*16 + 3] != in2[i*16 + 3] * 3 + || out2[i*16 + 4] != in2[i*16 + 4] * 2 + || out2[i*16 + 5] != in2[i*16 + 5] * 3 + || out2[i*16 + 6] != in2[i*16 + 6] * 2 + || out2[i*16 + 7] != in2[i*16 + 7] * 4 + || out2[i*16 + 8] != in2[i*16 + 8] * 2 + || out2[i*16 + 9] != in2[i*16 + 9] * 5 + || out2[i*16 + 10] != in2[i*16 + 10] * 2 + || out2[i*16 + 11] != in2[i*16 + 11] * 3 + || out2[i*16 + 12] != in2[i*16 + 12] * 4 + || out2[i*16 + 13] != in2[i*16 + 13] * 4 + || out2[i*16 + 14] != in2[i*16 + 14] * 3 + || out2[i*16 + 15] != in2[i*16 + 15] * 2) + abort (); + + } + + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" {target { ! { vect_int_mult } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" {target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" {target { ! { vect_int_mult } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-16.c b/gcc/testsuite/gcc.dg/vect/slp-16.c new file mode 100644 index 000000000..e5469d46c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-16.c @@ -0,0 +1,71 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int out[N*8]; +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned int in2[N*16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned int out2[N*16]; + +int +main1 () +{ + int i; + unsigned int a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + + /* SLP group of size that is not a multiple of vector size. + Unrolling by 2. */ + for (i = 0; i < N; i++) + { + a0 = in[i*2] + 5; + a1 = in[i*2 + 1] + 6; + + b0 = a0 * 3; + b1 = a1 * 2; + + out[i*2] = b0 - 2; + out[i*2 + 1] = b1 - 3; + + out2[i*6] = in2[i*6] * 2; + out2[i*6 + 1] = in2[i*6 + 1] * 3; + out2[i*6 + 2] = in2[i*6 + 2] * 4; + out2[i*6 + 3] = in2[i*6 + 3] * 2; + out2[i*6 + 4] = in2[i*6 + 4] * 4; + out2[i*6 + 5] = in2[i*6 + 5] * 3; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*2] != (in[i*2] + 5) * 3 - 2 + || out[i*2 + 1] != (in[i*2 + 1] + 6) * 2 - 3 + || out2[i*6] != in2[i*6] * 2 + || out2[i*6 + 1] != in2[i*6 + 1] * 3 + || out2[i*6 + 2] != in2[i*6 + 2] * 4 + || out2[i*6 + 3] != in2[i*6 + 3] * 2 + || out2[i*6 + 4] != in2[i*6 + 4] * 4 + || out2[i*6 + 5] != in2[i*6 + 5] * 3) + abort (); + } + + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_int_mult } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-17.c b/gcc/testsuite/gcc.dg/vect/slp-17.c new file mode 100644 index 000000000..b76346add --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-17.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned short out[N*8]; +unsigned short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned short in2[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned short out2[N*8]; + +int +main1 () +{ + int i; + + for (i = 0; i < N*2; i++) + { + out[i*2] = in[i*2] + 5; + out[i*2 + 1] = in[i*2 + 1] + 6; + + out2[i*4] = in2[i*4] + 2; + out2[i*4 + 1] = in2[i*4 + 1] + 2; + out2[i*4 + 2] = in2[i*4 + 2] + 1; + out2[i*4 + 3] = in2[i*4 + 3] + 3; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*2] != in[i*2] + 5 + || out[i*2 + 1] != in[i*2 + 1] + 6 + || out2[i*4] != in2[i*4] + 2 + || out2[i*4 + 1] != in2[i*4 + 1] + 2 + || out2[i*4 + 2] != in2[i*4 + 2] + 1 + || out2[i*4 + 3] != in2[i*4 + 3] + 3) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-18.c b/gcc/testsuite/gcc.dg/vect/slp-18.c new file mode 100644 index 000000000..8cdb0ddb9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-18.c @@ -0,0 +1,97 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_intfloat_cvt } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + float out2[N*8]; + + for (i = 0; i < N; i++) + { + + a0 = in[i*8] + 5; + a1 = in[i*8 + 1] + 6; + a2 = in[i*8 + 2] + 7; + a3 = in[i*8 + 3] + 8; + a4 = in[i*8 + 4] + 9; + a5 = in[i*8 + 5] + 10; + a6 = in[i*8 + 6] + 11; + a7 = in[i*8 + 7] + 12; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + b7 = a7 * 2; + + out[i*8] = b0 - 2; + out[i*8 + 1] = b1 - 3; + out[i*8 + 2] = b2 - 2; + out[i*8 + 3] = b3 - 1; + out[i*8 + 4] = b4 - 8; + out[i*8 + 5] = b5 - 7; + out[i*8 + 6] = b6 - 3; + out[i*8 + 7] = b7 - 7; + + + out2[i*8] = (float) b0; + out2[i*8 + 1] = (float) b1; + out2[i*8 + 2] = (float) b2; + out2[i*8 + 3] = (float) b3; + out2[i*8 + 4] = (float) b4; + out2[i*8 + 5] = (float) b5; + out2[i*8 + 6] = (float) b6; + out2[i*8 + 7] = (float) b7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (in[i*8] + 5) * 3 - 2 + || out[i*8 + 1] != (in[i*8 + 1] + 6) * 2 - 3 + || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 + || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 + || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 + || out[i*8 + 5] != (in[i*8 + 5] + 10) * 4 - 7 + || out[i*8 + 6] != (in[i*8 + 6] + 11) * 3 - 3 + || out[i*8 + 7] != (in[i*8 + 7] + 12) * 2 - 7) + abort (); + + if (out2[i*8] != (float) ((in[i*8] + 5) * 3) + || out2[i*8 + 1] != (float) ((in[i*8 + 1] + 6) * 2) + || out2[i*8 + 2] != (float) ((in[i*8 + 2] + 7) * 12) + || out2[i*8 + 3] != (float) ((in[i*8 + 3] + 8) * 5) + || out2[i*8 + 4] != (float) ((in[i*8 + 4] + 9) * 8) + || out2[i*8 + 5] != (float) ((in[i*8 + 5] + 10) * 4) + || out2[i*8 + 6] != (float) ((in[i*8 + 6] + 11) * 3) + || out2[i*8 + 7] != (float) ((in[i*8 + 7] + 12) * 2)) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_strided } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-19.c b/gcc/testsuite/gcc.dg/vect/slp-19.c new file mode 100644 index 000000000..349c5ec6c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-19.c @@ -0,0 +1,154 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int +main1 () +{ + unsigned int i; + unsigned int out[N*8]; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + unsigned int ia[N*2], a0, a1, a2, a3; + + for (i = 0; i < N; i++) + { + out[i*8] = in[i*8]; + out[i*8 + 1] = in[i*8 + 1]; + out[i*8 + 2] = in[i*8 + 2]; + out[i*8 + 3] = in[i*8 + 3]; + out[i*8 + 4] = in[i*8 + 4]; + out[i*8 + 5] = in[i*8 + 5]; + out[i*8 + 6] = in[i*8 + 6]; + out[i*8 + 7] = in[i*8 + 7]; + + ia[i] = in[i*8 + 2]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + || out[i*8 + 1] != in[i*8 + 1] + || out[i*8 + 2] != in[i*8 + 2] + || out[i*8 + 3] != in[i*8 + 3] + || out[i*8 + 4] != in[i*8 + 4] + || out[i*8 + 5] != in[i*8 + 5] + || out[i*8 + 6] != in[i*8 + 6] + || out[i*8 + 7] != in[i*8 + 7] + || ia[i] != in[i*8 + 2]) + abort (); + } + + for (i = 0; i < N*2; i++) + { + a0 = in[i*4] + 1; + a1 = in[i*4 + 1] + 2; + a2 = in[i*4 + 2] + 3; + a3 = in[i*4 + 3] + 4; + + out[i*4] = a0; + out[i*4 + 1] = a1; + out[i*4 + 2] = a2; + out[i*4 + 3] = a3; + + ia[i] = a2; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != in[i*4] + 1 + || out[i*4 + 1] != in[i*4 + 1] + 2 + || out[i*4 + 2] != in[i*4 + 2] + 3 + || out[i*4 + 3] != in[i*4 + 3] + 4 + || ia[i] != in[i*4 + 2] + 3) + abort (); + } + + /* The last stmt requires interleaving of not power of 2 size - not + vectorizable. */ + for (i = 0; i < N/2; i++) + { + out[i*12] = in[i*12]; + out[i*12 + 1] = in[i*12 + 1]; + out[i*12 + 2] = in[i*12 + 2]; + out[i*12 + 3] = in[i*12 + 3]; + out[i*12 + 4] = in[i*12 + 4]; + out[i*12 + 5] = in[i*12 + 5]; + out[i*12 + 6] = in[i*12 + 6]; + out[i*12 + 7] = in[i*12 + 7]; + out[i*12 + 8] = in[i*12 + 8]; + out[i*12 + 9] = in[i*12 + 9]; + out[i*12 + 10] = in[i*12 + 10]; + out[i*12 + 11] = in[i*12 + 11]; + + ia[i] = in[i*12 + 7]; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*12] != in[i*12] + || out[i*12 + 1] != in[i*12 + 1] + || out[i*12 + 2] != in[i*12 + 2] + || out[i*12 + 3] != in[i*12 + 3] + || out[i*12 + 4] != in[i*12 + 4] + || out[i*12 + 5] != in[i*12 + 5] + || out[i*12 + 6] != in[i*12 + 6] + || out[i*12 + 7] != in[i*12 + 7] + || out[i*12 + 8] != in[i*12 + 8] + || out[i*12 + 9] != in[i*12 + 9] + || out[i*12 + 10] != in[i*12 + 10] + || out[i*12 + 11] != in[i*12 + 11] + || ia[i] != in[i*12 + 7]) + abort (); + } + + /* Hybrid SLP with unrolling by 2. */ + for (i = 0; i < N; i++) + { + out[i*6] = in[i*6]; + out[i*6 + 1] = in[i*6 + 1]; + out[i*6 + 2] = in[i*6 + 2]; + out[i*6 + 3] = in[i*6 + 3]; + out[i*6 + 4] = in[i*6 + 4]; + out[i*6 + 5] = in[i*6 + 5]; + + ia[i] = i; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*6] != in[i*6] + || out[i*6 + 1] != in[i*6 + 1] + || out[i*6 + 2] != in[i*6 + 2] + || out[i*6 + 3] != in[i*6 + 3] + || out[i*6 + 4] != in[i*6 + 4] + || out[i*6 + 5] != in[i*6 + 5] + || ia[i] != i) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target vect_strided_wide } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { vect_strided_wide } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target vect_strided_wide } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { ! { vect_strided_wide } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-2.c b/gcc/testsuite/gcc.dg/vect/slp-2.c new file mode 100644 index 000000000..69e1ed5e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-2.c @@ -0,0 +1,145 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int +main1 (unsigned short a0, unsigned short a1, unsigned short a2, + unsigned short a3, unsigned short a4, unsigned short a5, + unsigned short a6, unsigned short a7, unsigned short a8, + unsigned short a9, unsigned short a10, unsigned short a11, + unsigned short a12, unsigned short a13, unsigned short a14, + unsigned short a15) +{ + int i; + unsigned short out[N*16]; + + for (i = 0; i < N; i++) + { + out[i*4] = a8; + out[i*4 + 1] = a1; + out[i*4 + 2] = a2; + out[i*4 + 3] = a3; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != a8 + || out[i*4 + 1] != a1 + || out[i*4 + 2] != a2 + || out[i*4 + 3] != a3) + abort (); + } + + for (i = 0; i < N; i++) + { + out[i*16] = a8; + out[i*16 + 1] = a7; + out[i*16 + 2] = a1; + out[i*16 + 3] = a2; + out[i*16 + 4] = a8; + out[i*16 + 5] = a5; + out[i*16 + 6] = a5; + out[i*16 + 7] = a4; + out[i*16 + 8] = a12; + out[i*16 + 9] = a13; + out[i*16 + 10] = a14; + out[i*16 + 11] = a15; + out[i*16 + 12] = a6; + out[i*16 + 13] = a9; + out[i*16 + 14] = a0; + out[i*16 + 15] = a7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*16] != a8 + || out[i*16 + 1] != a7 + || out[i*16 + 2] != a1 + || out[i*16 + 3] != a2 + || out[i*16 + 4] != a8 + || out[i*16 + 5] != a5 + || out[i*16 + 6] != a5 + || out[i*16 + 7] != a4 + || out[i*16 + 8] != a12 + || out[i*16 + 9] != a13 + || out[i*16 + 10] != a14 + || out[i*16 + 11] != a15 + || out[i*16 + 12] != a6 + || out[i*16 + 13] != a9 + || out[i*16 + 14] != a0 + || out[i*16 + 15] != a7) + abort (); + } + + /* SLP with unrolling by 8. */ + for (i = 0; i < N; i++) + { + out[i*3] = a8; + out[i*3 + 1] = a1; + out[i*3 + 2] = a2; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*3] != a8 + || out[i*3 + 1] != a1 + || out[i*3 + 2] != a2) + abort (); + } + + /* SLP with unrolling by 8. */ + for (i = 0; i < N; i++) + { + out[i*11] = a8; + out[i*11 + 1] = a7; + out[i*11 + 2] = a1; + out[i*11 + 3] = a2; + out[i*11 + 4] = a8; + out[i*11 + 5] = a5; + out[i*11 + 6] = a5; + out[i*11 + 7] = a4; + out[i*11 + 8] = a12; + out[i*11 + 9] = a13; + out[i*11 + 10] = a14; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*11] != a8 + || out[i*11 + 1] != a7 + || out[i*11 + 2] != a1 + || out[i*11 + 3] != a2 + || out[i*11 + 4] != a8 + || out[i*11 + 5] != a5 + || out[i*11 + 6] != a5 + || out[i*11 + 7] != a4 + || out[i*11 + 8] != a12 + || out[i*11 + 9] != a13 + || out[i*11 + 10] != a14) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-20.c b/gcc/testsuite/gcc.dg/vect/slp-20.c new file mode 100644 index 000000000..5fd85743b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-20.c @@ -0,0 +1,115 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int +main1 (unsigned short a0, unsigned short a1, unsigned short a2, + unsigned short a3, unsigned short a4, unsigned short a5, + unsigned short a6, unsigned short a7, unsigned short a8) +{ + int i; + unsigned short out[N*8], out2[N*8], b0, b1, b2, b3, b4, b5, b6, b7, b8; + + for (i = 0; i < N; i++) + { + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 + 5; + b4 = a4 + 4; + b5 = a5 + 3; + + out[i*4] = b0; + out[i*4 + 1] = b1; + out[i*4 + 2] = b2; + out[i*4 + 3] = b3; + + out2[i*4] = b0; + out2[i*4 + 1] = b1; + out2[i*4 + 2] = b4; + out2[i*4 + 3] = b5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != b0 + || out[i*4 + 1] != b1 + || out[i*4 + 2] != b2 + || out[i*4 + 3] != b3) + abort (); + + if (out2[i*4] != b0 + || out2[i*4 + 1] != b1 + || out2[i*4 + 2] != b4 + || out2[i*4 + 3] != b5) + abort (); + } + + for (i = 0; i < N; i++) + { + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 + 5; + b4 = a4 + 4; + b5 = a5 + 3; + b6 = a6 + 2; + b7 = a7 + 1; + b8 = a8 + 9; + + out[i*4] = b0; + out[i*4 + 1] = b1; + out[i*4 + 2] = b2; + out[i*4 + 3] = b3; + + out2[i*8] = b0; + out2[i*8 + 1] = b1; + out2[i*8 + 2] = b4; + out2[i*8 + 3] = b5; + out2[i*8 + 4] = b6; + out2[i*8 + 5] = b2; + out2[i*8 + 6] = b7; + out2[i*8 + 7] = b8; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != b0 + || out[i*4 + 1] != b1 + || out[i*4 + 2] != b2 + || out[i*4 + 3] != b3) + abort (); + + if (out2[i*8] != b0 + || out2[i*8 + 1] != b1 + || out2[i*8 + 2] != b4 + || out2[i*8 + 3] != b5 + || out2[i*8 + 4] != b6 + || out2[i*8 + 5] != b2 + || out2[i*8 + 6] != b7 + || out2[i*8 + 7] != b8) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (8,7,6,5,4,3,2,1,0); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-21.c b/gcc/testsuite/gcc.dg/vect/slp-21.c new file mode 100644 index 000000000..b4f4e24e0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-21.c @@ -0,0 +1,207 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int +main1 () +{ + unsigned short i; + unsigned short out[N*8], out2[N*8], b0, b1, b2, b3, b4, a0, a1, a2, a3, b5; + unsigned short in[N*8]; + + for (i = 0; i < N*8; i++) + { + in[i] = i; + } + + /* Different operations in both cases - vectorization with interleaving. */ + for (i = 0; i < N; i++) + { + a0 = in[i*4]; + a1 = in[i*4 + 1]; + a2 = in[i*4 + 2]; + a3 = in[i*4 + 3]; + + b0 = a0 * 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 * 5; + + b4 = a2 + 4; + b5 = a3 + 3; + + out[i*4] = b0; + out[i*4 + 1] = b1; + out[i*4 + 2] = b2; + out[i*4 + 3] = b3; + + out2[i*4] = b0; + out2[i*4 + 1] = b1; + out2[i*4 + 2] = b4; + out2[i*4 + 3] = b5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + a0 = in[i*4]; + a1 = in[i*4 + 1]; + a2 = in[i*4 + 2]; + a3 = in[i*4 + 3]; + + b0 = a0 * 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 * 5; + + b4 = a2 + 4; + b5 = a3 + 3; + + if (out[i*4] != b0 + || out[i*4 + 1] != b1 + || out[i*4 + 2] != b2 + || out[i*4 + 3] != b3) + abort (); + + if (out2[i*4] != b0 + || out2[i*4 + 1] != b1 + || out2[i*4 + 2] != b4 + || out2[i*4 + 3] != b5) + abort (); + } + + /* Different operations in the first case - vectorization with interleaving. */ + for (i = 0; i < N; i++) + { + a0 = in[i*4]; + a1 = in[i*4 + 1]; + a2 = in[i*4 + 2]; + a3 = in[i*4 + 3]; + + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 * 5; + + b4 = a2 + 4; + b5 = a3 + 3; + + out[i*4] = b0; + out[i*4 + 1] = b1; + out[i*4 + 2] = b2; + out[i*4 + 3] = b3; + + out2[i*4] = b0; + out2[i*4 + 1] = b1; + out2[i*4 + 2] = b4; + out2[i*4 + 3] = b5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + a0 = in[i*4]; + a1 = in[i*4 + 1]; + a2 = in[i*4 + 2]; + a3 = in[i*4 + 3]; + + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 * 5; + + b4 = a2 + 4; + b5 = a3 + 3; + + if (out[i*4] != b0 + || out[i*4 + 1] != b1 + || out[i*4 + 2] != b2 + || out[i*4 + 3] != b3) + abort (); + + if (out2[i*4] != b0 + || out2[i*4 + 1] != b1 + || out2[i*4 + 2] != b4 + || out2[i*4 + 3] != b5) + abort (); + } + + + /* Different operations in the second case - vectorization with interleaving. */ + for (i = 0; i < N; i++) + { + a0 = in[i*4]; + a1 = in[i*4 + 1]; + a2 = in[i*4 + 2]; + a3 = in[i*4 + 3]; + + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 + 5; + + b4 = a2 * 4; + b5 = a3 + 3; + + out[i*4] = b0; + out[i*4 + 1] = b1; + out[i*4 + 2] = b2; + out[i*4 + 3] = b3; + + out2[i*4] = b0; + out2[i*4 + 1] = b1; + out2[i*4 + 2] = b4; + out2[i*4 + 3] = b5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + a0 = in[i*4]; + a1 = in[i*4 + 1]; + a2 = in[i*4 + 2]; + a3 = in[i*4 + 3]; + + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 + 5; + + b4 = a2 * 4; + b5 = a3 + 3; + + if (out[i*4] != b0 + || out[i*4 + 1] != b1 + || out[i*4 + 2] != b2 + || out[i*4 + 3] != b3) + abort (); + + if (out2[i*4] != b0 + || out2[i*4 + 1] != b1 + || out2[i*4 + 2] != b4 + || out2[i*4 + 3] != b5) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target { vect_strided || vect_extract_even_odd } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { vect_strided || vect_extract_even_odd } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_strided } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { ! { vect_strided } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-22.c b/gcc/testsuite/gcc.dg/vect/slp-22.c new file mode 100644 index 000000000..3f6692816 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-22.c @@ -0,0 +1,134 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int +main1 (unsigned short a0, unsigned short a1, unsigned short a2, + unsigned short a3, unsigned short a4, unsigned short a5, + unsigned short a6, unsigned short a7, unsigned short a8) +{ + int i; + unsigned short out[N*8], out2[N*8], out3[N*8], b0, b1, b2, b3, b4, b5, b6, b7, b8; + + for (i = 0; i < N; i++) + { + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 + 5; + b4 = a4 + 4; + b5 = a5 + 3; + + out[i*4] = b0; + out[i*4 + 1] = b1; + out[i*4 + 2] = b2; + out[i*4 + 3] = b3; + + out2[i*4] = b0; + out2[i*4 + 1] = b1; + out2[i*4 + 2] = b4; + out2[i*4 + 3] = b5; + + out3[i*4] = b2; + out3[i*4 + 1] = b1; + out3[i*4 + 2] = b4; + out3[i*4 + 3] = b5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != b0 + || out[i*4 + 1] != b1 + || out[i*4 + 2] != b2 + || out[i*4 + 3] != b3) + abort (); + + + if (out2[i*4] != b0 + || out2[i*4 + 1] != b1 + || out2[i*4 + 2] != b4 + || out2[i*4 + 3] != b5) + abort (); + + if (out3[i*4] != b2 + || out3[i*4 + 1] != b1 + || out3[i*4 + 2] != b4 + || out3[i*4 + 3] != b5) + abort (); + } + + for (i = 0; i < N; i++) + { + b0 = a0 + 8; + b1 = a1 + 7; + b2 = a2 + 6; + b3 = a3 + 5; + b4 = a4 + 4; + b5 = a5 + 3; + b6 = a6 + 2; + b7 = a7 + 1; + b8 = a8 + 9; + + out[i*4] = b0; + out[i*4 + 1] = b1; + out[i*4 + 2] = b2; + out[i*4 + 3] = b3; + + out2[i*8] = b0; + out2[i*8 + 1] = b1; + out2[i*8 + 2] = b4; + out2[i*8 + 3] = b5; + out2[i*8 + 4] = b6; + out2[i*8 + 5] = b2; + out2[i*8 + 6] = b7; + out2[i*8 + 7] = b8; + + out3[2*i + 1] = a0; + out3[2*i] = b8; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != b0 + || out[i*4 + 1] != b1 + || out[i*4 + 2] != b2 + || out[i*4 + 3] != b3) + abort (); + + if (out2[i*8] != b0 + || out2[i*8 + 1] != b1 + || out2[i*8 + 2] != b4 + || out2[i*8 + 3] != b5 + || out2[i*8 + 4] != b6 + || out2[i*8 + 5] != b2 + || out2[i*8 + 6] != b7 + || out2[i*8 + 7] != b8) + abort (); + + if (out3[2*i] != b8 + || out3[2*i+1] != a0) + abort(); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (8,7,6,5,4,3,2,1,0); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 6 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-23.c b/gcc/testsuite/gcc.dg/vect/slp-23.c new file mode 100644 index 000000000..3a64284b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-23.c @@ -0,0 +1,113 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + int a; + int b; + int c; + int d; + int e; + int f; + int g; + int h; +} s; + +int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + + for (i = 0; i < N; i++) + { + res[i].c = ptr->c + ptr->c; + res[i].a = ptr->a + ptr->a; + res[i].d = ptr->d + ptr->d; + res[i].b = ptr->b + ptr->b; + res[i].f = ptr->f + ptr->f; + res[i].e = ptr->e + ptr->e; + res[i].h = ptr->h + ptr->h; + res[i].g = ptr->g + ptr->g; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].c + arr[i].c + || res[i].a != arr[i].a + arr[i].a + || res[i].d != arr[i].d + arr[i].d + || res[i].b != arr[i].b + arr[i].b + || res[i].f != arr[i].f + arr[i].f + || res[i].e != arr[i].e + arr[i].e + || res[i].h != arr[i].h + arr[i].h + || res[i].g != arr[i].g + arr[i].g) + abort(); + } + + ptr = arr; + for (i = 0; i < N; i++) + { + res[i].c = ptr->c + ptr->c; + res[i].a = ptr->a + ptr->a; + res[i].d = ptr->d + ptr->d; + res[i].b = ptr->b + ptr->b; + res[i].f = ptr->f + ptr->f; + res[i].e = ptr->e + ptr->e; + res[i].h = ptr->e + ptr->e; + res[i].g = ptr->g + ptr->g; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].c + arr[i].c + || res[i].a != arr[i].a + arr[i].a + || res[i].d != arr[i].d + arr[i].d + || res[i].b != arr[i].b + arr[i].b + || res[i].f != arr[i].f + arr[i].f + || res[i].e != arr[i].e + arr[i].e + || res[i].h != arr[i].e + arr[i].e + || res[i].g != arr[i].g + arr[i].g) + abort(); + } + +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i * 3 + 5; + arr[i].f = i * 5; + arr[i].g = i - 3; + arr[i].h = 56; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { vect_strided_wide } && {! { vect_no_align} } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { vect_strided_wide || vect_no_align} } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-24.c b/gcc/testsuite/gcc.dg/vect/slp-24.c new file mode 100644 index 000000000..61c53f08f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-24.c @@ -0,0 +1,82 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; +} s; + +unsigned char ub[N*2] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +void +main1 (unsigned char x, unsigned char max_result, unsigned char min_result, s *arr) +{ + int i; + unsigned char udiff = 2; + unsigned char umax = x; + unsigned char umin = x; + unsigned char ua1[N*2]; + s *pIn = arr; + s out[N]; + + for (i = 0; i < N; i++) { + udiff += (unsigned char)(ub[i] - uc[i]); + + ua1[2*i+1] = ub[2*i+1]; + ua1[2*i] = ub[2*i]; + + out[i].d = pIn->d - 1; + out[i].b = pIn->b - 4; + out[i].c = pIn->c - 8; + out[i].a = pIn->a - 3; + + pIn++; + } + + for (i = 0; i < N; i++) { + if (ua1[2*i] != ub[2*i] + || ua1[2*i+1] != ub[2*i+1] + || out[i].a != arr[i].a - 3 + || out[i].b != arr[i].b - 4 + || out[i].c != arr[i].c - 8 + || out[i].d != arr[i].d - 1) + abort(); + } + + /* check results: */ + if (udiff != DIFF) + abort (); +} + +int main (void) +{ + int i; + s arr[N]; + + for (i = 0; i < N; i++) + { + arr[i].a = i + 9; + arr[i].b = i * 2 + 10; + arr[i].c = 17; + arr[i].d = i+34; + if (arr[i].a == 178) + abort(); + } + check_vect (); + + main1 (100, 100, 1, arr); + main1 (0, 15, 0, arr); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align && ilp32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { xfail { vect_no_align && ilp32 } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-25.c b/gcc/testsuite/gcc.dg/vect/slp-25.c new file mode 100644 index 000000000..497563703 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-25.c @@ -0,0 +1,61 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +/* Unaligned stores. */ + +int ia[N+2]; +short sa[N+2]; + +int main1 (int n) +{ + int i; + + for (i = 1; i <= N/2; i++) + { + ia[2*i] = 25; + ia[2*i + 1] = 5; + } + + /* check results: */ + for (i = 1; i <= N/2; i++) + { + if (ia[2*i] != 25 + || ia[2*i + 1] != 5) + abort (); + } + + for (i = 1; i <= n/2; i++) + { + sa[2*i] = 25; + sa[2*i + 1] = 5; + } + + /* check results: */ + for (i = 1; i <= n/2; i++) + { + if (sa[2*i] != 25 + || sa[2*i + 1] != 5) + abort (); + } + + + return 0; +} + +int main (void) +{ + + check_vect (); + + return main1 (N); +} + +/* { 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" 2 "vect" { xfail { vect_no_align || { ! vect_natural_alignment } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-26.c b/gcc/testsuite/gcc.dg/vect/slp-26.c new file mode 100644 index 000000000..6821b2ced --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-26.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + unsigned short out[N*8], a[N], b[N] = {3,6,9,12,15,18,21,24}; + + /* Partial SLP is not supported. */ + for (i = 0; i < N; i++) + { + out[i*4] = in[i*4]; + out[i*4 + 1] = in[i*4 + 1]; + out[i*4 + 2] = in[i*4 + 2]; + out[i*4 + 3] = in[i*4 + 3]; + + a[i] = b[i] / 3; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*4] != in[i*4] + || out[i*4 + 1] != in[i*4 + 1] + || out[i*4 + 2] != in[i*4 + 2] + || out[i*4 + 3] != in[i*4 + 3] + || a[i] != b[i] / 3) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-28.c b/gcc/testsuite/gcc.dg/vect/slp-28.c new file mode 100644 index 000000000..41c482709 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-28.c @@ -0,0 +1,86 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +unsigned short in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +unsigned short in2[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +unsigned short in3[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +unsigned short check[N] = {0,1,2,3,5,6,7,8,10,11,12,13,15,16,17,18,20,21,22,23,25,26,27,28,30,31,32,33,35,36,37,38}; +unsigned short check3[N] = {0,1,2,3,4,5,6,7,8,9,10,11,5,6,7,8,9,10,11,12,13,14,15,16,10,11,12,13,14,15,16,17}; + +int +main1 () +{ + int i; + + for (i = 0; i < N/4; i++) + { + in[i*4] = in[i*4] + 5; + in[i*4 + 1] = in[i*4 + 1] + 5; + in[i*4 + 2] = in[i*4 + 2] + 5; + in[i*4 + 3] = in[i*4 + 3] + 5; + + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (in[i] != i+5) + abort (); + } + + /* Not vectorizable because of data dependencies. */ + for (i = 1; i < N/4; i++) + { + in2[i*4] = in2[(i-1)*4] + 5; + in2[i*4 + 1] = in2[(i-1)*4 + 1] + 5; + in2[i*4 + 2] = in2[(i-1)*4 + 2] + 5; + in2[i*4 + 3] = in2[(i-1)*4 + 3] + 5; + + } + + /* check results: */ + for (i = 4; i < N; i++) + { + if (in2[i] != check[i]) + abort (); + } + + /* Not vectorizable because of data dependencies: distance 3 is greater than + the actual VF with SLP (2), but the analysis fail to detect that for now. */ + for (i = 3; i < N/4; i++) + { + in3[i*4] = in3[(i-3)*4] + 5; + in3[i*4 + 1] = in3[(i-3)*4 + 1] + 5; + in3[i*4 + 2] = in3[(i-3)*4 + 2] + 5; + in3[i*4 + 3] = in3[(i-3)*4 + 3] + 5; + + } + + /* check results: */ + for (i = 12; i < N; i++) + { + if (in3[i] != check3[i]) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-3.c b/gcc/testsuite/gcc.dg/vect/slp-3.c new file mode 100644 index 000000000..8c99b01e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-3.c @@ -0,0 +1,148 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +int +main1 () +{ + int i; + unsigned short out[N*8]; + + for (i = 0; i < N; i++) + { + out[i*8] = in[i*8]; + out[i*8 + 1] = in[i*8 + 1]; + out[i*8 + 2] = in[i*8 + 2]; + out[i*8 + 3] = in[i*8 + 3]; + out[i*8 + 4] = in[i*8 + 4]; + out[i*8 + 5] = in[i*8 + 5]; + out[i*8 + 6] = in[i*8 + 6]; + out[i*8 + 7] = in[i*8 + 7]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + || out[i*8 + 1] != in[i*8 + 1] + || out[i*8 + 2] != in[i*8 + 2] + || out[i*8 + 3] != in[i*8 + 3] + || out[i*8 + 4] != in[i*8 + 4] + || out[i*8 + 5] != in[i*8 + 5] + || out[i*8 + 6] != in[i*8 + 6] + || out[i*8 + 7] != in[i*8 + 7]) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = in[i*4]; + out[i*4 + 1] = in[i*4 + 1]; + out[i*4 + 2] = in[i*4 + 2]; + out[i*4 + 3] = in[i*4 + 3]; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != in[i*4] + || out[i*4 + 1] != in[i*4 + 1] + || out[i*4 + 2] != in[i*4 + 2] + || out[i*4 + 3] != in[i*4 + 3]) + abort (); + } + + for (i = 0; i < N/2; i++) + { + out[i*16] = in[i*16]; + out[i*16 + 1] = in[i*16 + 1]; + out[i*16 + 2] = in[i*16 + 2]; + out[i*16 + 3] = in[i*16 + 3]; + out[i*16 + 4] = in[i*16 + 4]; + out[i*16 + 5] = in[i*16 + 5]; + out[i*16 + 6] = in[i*16 + 6]; + out[i*16 + 7] = in[i*16 + 7]; + out[i*16 + 8] = in[i*16 + 8]; + out[i*16 + 9] = in[i*16 + 9]; + out[i*16 + 10] = in[i*16 + 10]; + out[i*16 + 11] = in[i*16 + 11]; + out[i*16 + 12] = in[i*16 + 12]; + out[i*16 + 13] = in[i*16 + 13]; + out[i*16 + 14] = in[i*16 + 14]; + out[i*16 + 15] = in[i*16 + 15]; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*16] != in[i*16] + || out[i*16 + 1] != in[i*16 + 1] + || out[i*16 + 2] != in[i*16 + 2] + || out[i*16 + 3] != in[i*16 + 3] + || out[i*16 + 4] != in[i*16 + 4] + || out[i*16 + 5] != in[i*16 + 5] + || out[i*16 + 6] != in[i*16 + 6] + || out[i*16 + 7] != in[i*16 + 7] + || out[i*16 + 8] != in[i*16 + 8] + || out[i*16 + 9] != in[i*16 + 9] + || out[i*16 + 10] != in[i*16 + 10] + || out[i*16 + 11] != in[i*16 + 11] + || out[i*16 + 12] != in[i*16 + 12] + || out[i*16 + 13] != in[i*16 + 13] + || out[i*16 + 14] != in[i*16 + 14] + || out[i*16 + 15] != in[i*16 + 15]) + abort (); + } + + /* SLP with unrolling by 8. */ + for (i = 0; i < N/2; i++) + { + out[i*9] = in[i*9]; + out[i*9 + 1] = in[i*9 + 1]; + out[i*9 + 2] = in[i*9 + 2]; + out[i*9 + 3] = in[i*9 + 3]; + out[i*9 + 4] = in[i*9 + 4]; + out[i*9 + 5] = in[i*9 + 5]; + out[i*9 + 6] = in[i*9 + 6]; + out[i*9 + 7] = in[i*9 + 7]; + out[i*9 + 8] = in[i*9 + 8]; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*9] != in[i*9] + || out[i*9 + 1] != in[i*9 + 1] + || out[i*9 + 2] != in[i*9 + 2] + || out[i*9 + 3] != in[i*9 + 3] + || out[i*9 + 4] != in[i*9 + 4] + || out[i*9 + 5] != in[i*9 + 5] + || out[i*9 + 6] != in[i*9 + 6] + || out[i*9 + 7] != in[i*9 + 7] + || out[i*9 + 8] != in[i*9 + 8]) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-33.c b/gcc/testsuite/gcc.dg/vect/slp-33.c new file mode 100644 index 000000000..4b67d894e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-33.c @@ -0,0 +1,111 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +int +main1 () +{ + int i; + unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + float out2[N*8]; + + /* SLP with unrolling by 4. */ + for (i = 0; i < N; i++) + { + a0 = in[i*7] + 5; + a1 = in[i*7 + 1] + 6; + a2 = in[i*7 + 2] + 7; + a3 = in[i*7 + 3] + 8; + a4 = in[i*7 + 4] + 9; + a5 = in[i*7 + 5] + 10; + a6 = in[i*7 + 6] + 11; + + b0 = a0 * 3; + b1 = a1 * 2; + b2 = a2 * 12; + b3 = a3 * 5; + b4 = a4 * 8; + b5 = a5 * 4; + b6 = a6 * 3; + + out[i*7] = b0 - 2; + out[i*7 + 1] = b1 - 3; + out[i*7 + 2] = b2 - 2; + out[i*7 + 3] = b3 - 1; + out[i*7 + 4] = b4 - 8; + out[i*7 + 5] = b5 - 7; + out[i*7 + 6] = b6 - 3; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*7] != (in[i*7] + 5) * 3 - 2 + || out[i*7 + 1] != (in[i*7 + 1] + 6) * 2 - 3 + || out[i*7 + 2] != (in[i*7 + 2] + 7) * 12 - 2 + || out[i*7 + 3] != (in[i*7 + 3] + 8) * 5 - 1 + || out[i*7 + 4] != (in[i*7 + 4] + 9) * 8 - 8 + || out[i*7 + 5] != (in[i*7 + 5] + 10) * 4 - 7 + || out[i*7 + 6] != (in[i*7 + 6] + 11) * 3 - 3) + abort (); + } + + /* SLP with unrolling by 4. */ + for (i = 0; i < N*2; i++) + { + out[i*3] = (in[i*3] + 2) * 3; + out[i*3 + 1] = (in[i*3 + 1] + 2) * 7; + out[i*3 + 2] = (in[i*3 + 2] + 7) * 3; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*3] != (in[i*3] + 2) * 3 + || out[i*3 + 1] != (in[i*3 + 1] + 2) * 7 + || out[i*3 + 2] != (in[i*3 + 2] + 7) * 3) + abort (); + } + + /* SLP with unrolling by 4. */ + for (i = 0; i < N*2; i++) + { + out2[i*3] = (float) (in[i*3] * 2 + 5) ; + out2[i*3 + 1] = (float) (in[i*3 + 1] * 3 + 7); + out2[i*3 + 2] = (float) (in[i*3 + 2] * 5 + 4); + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out2[i*3] != (float) (in[i*3] * 2 + 5) + || out2[i*3 + 1] != (float) (in[i*3 + 1] * 3 + 7) + || out2[i*3 + 2] != (float) (in[i*3 + 2] * 5 + 4)) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {target {vect_uintfloat_cvt && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {target {{! { vect_uintfloat_cvt}} && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" {target {{! { vect_uintfloat_cvt}} && {! {vect_int_mult}}} } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" {target {vect_uintfloat_cvt && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" {target {{! { vect_uintfloat_cvt}} && vect_int_mult} } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" {target {{! { vect_uintfloat_cvt}} && {! {vect_int_mult}}} } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-34.c b/gcc/testsuite/gcc.dg/vect/slp-34.c new file mode 100644 index 000000000..63dbab051 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-34.c @@ -0,0 +1,61 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned short in2[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +int +main1 () +{ + int i; + unsigned short out[N*8]; + unsigned short out2[N*8]; + + /* SLP with unrolling by 8. */ + for (i = 0; i < N; i++) + { + out[i*3] = in[i*3] + 5; + out[i*3 + 1] = in[i*3 + 1] + 6; + out[i*3 + 2] = in[i*3 + 2] + 16; + + out2[i*5] = in2[i*5] + 2; + out2[i*5 + 1] = in2[i*5 + 1] + 2; + out2[i*5 + 2] = in2[i*5 + 2] + 1; + out2[i*5 + 3] = in2[i*5 + 3] + 3; + out2[i*5 + 4] = in2[i*5 + 4] + 13; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*3] != in[i*3] + 5 + || out[i*3 + 1] != in[i*3 + 1] + 6 + || out[i*3 + 2] != in[i*3 + 2] + 16 + || out2[i*5] != in2[i*5] + 2 + || out2[i*5 + 1] != in2[i*5 + 1] + 2 + || out2[i*5 + 2] != in2[i*5 + 2] + 1 + || out2[i*5 + 3] != in2[i*5 + 3] + 3 + || out2[i*5 + 4] != in2[i*5 + 4] + 13) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-35.c b/gcc/testsuite/gcc.dg/vect/slp-35.c new file mode 100644 index 000000000..f75691431 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-35.c @@ -0,0 +1,73 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + int a; + int b; + int c; + int d; + int e; +} s; + +int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + + /* SLP with unrolling by 4. */ + for (i = 0; i < N; i++) + { + res[i].c = ptr->c + ptr->c; + res[i].a = ptr->a + ptr->a; + res[i].d = ptr->d + ptr->d; + res[i].b = ptr->b + ptr->b; + res[i].e = ptr->e + ptr->e; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].c + arr[i].c + || res[i].a != arr[i].a + arr[i].a + || res[i].d != arr[i].d + arr[i].d + || res[i].b != arr[i].b + arr[i].b + || res[i].e != arr[i].e + arr[i].e) + abort(); + } + +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i * 3 + 5; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-36.c b/gcc/testsuite/gcc.dg/vect/slp-36.c new file mode 100644 index 000000000..8480c4a05 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-36.c @@ -0,0 +1,76 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_shift } */ + +#define N 32 + +/* All the loops are vectorizable on platforms with vector shift argument. */ + +void +test_1 (void) +{ + static unsigned int bm[N]; + static unsigned int cm[N]; + int j; + + /* Vectorizable on platforms with scalar shift argument. */ + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= 8; + bm[2*j+1] <<= 8; + } + + /* Not vectorizable on platforms with scalar shift argument. */ + for (j = 0; j < N/2; j++) + { + cm[2*j] <<= 8; + cm[2*j+1] <<= 7; + } +} + +void +test_2 (int a, int b) +{ + static unsigned int bm[N]; + static unsigned int cm[N]; + int j; + + /* Vectorizable on platforms with scalar shift argument. */ + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= a; + bm[2*j+1] <<= a; + } + + /* Not vectorizable on platforms with scalar shift argument. */ + for (j = 0; j < N/2; j++) + { + cm[2*j] <<= a; + cm[2*j+1] <<= b; + } +} + +void +test_3 (void) +{ + static unsigned int bm[N]; + int am[N]; + int j; + + /* Not vectorizable on platforms with scalar shift argument. */ + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= am[j]; + bm[2*j+1] <<= am[j]; + } + + /* Not vectorizable on platforms with scalar shift argument. */ + for (j = 0; j < N/2; j++) + { + bm[2*j] <<= am[2*j]; + bm[2*j+1] <<= am[2*j+1]; + } + +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-37.c b/gcc/testsuite/gcc.dg/vect/slp-37.c new file mode 100644 index 000000000..48642db96 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-37.c @@ -0,0 +1,67 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <stdlib.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + int a; + int b; + void *c; +} s1; + +int +foo1 (s1 *arr) +{ + int i; + s1 *ptr = arr; + + /* Different constant types - not SLPable. The group size is not power of 2, + interleaving is not supported either. */ + for (i = 0; i < N; i++) + { + ptr->a = 6; + ptr->b = 7; + ptr->c = NULL; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr[i].a != 6 + || arr[i].b != 7 + || arr[i].c != NULL) + abort(); + } +} + +int main (void) +{ + int i; + s1 arr1[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr1[i].a = i; + arr1[i].b = i * 2; + arr1[i].c = (void *)arr1; + + if (arr1[i].a == 178) + abort(); + } + + + foo1 (arr1); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-4.c b/gcc/testsuite/gcc.dg/vect/slp-4.c new file mode 100644 index 000000000..50ad2bd53 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-4.c @@ -0,0 +1,127 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int +main1 () +{ + int i; + unsigned short out[N*8]; + unsigned short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + unsigned int ia[N*2]; + + for (i = 0; i < N; i++) + { + out[i*8] = in[i*8]; + out[i*8 + 1] = in[i*8 + 1]; + out[i*8 + 2] = in[i*8 + 2]; + out[i*8 + 3] = in[i*8 + 3]; + out[i*8 + 4] = in[i*8 + 4]; + out[i*8 + 5] = in[i*8 + 5]; + out[i*8 + 6] = in[i*8 + 6]; + out[i*8 + 7] = in[i*8 + 7]; + + ia[i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + || out[i*8 + 1] != in[i*8 + 1] + || out[i*8 + 2] != in[i*8 + 2] + || out[i*8 + 3] != in[i*8 + 3] + || out[i*8 + 4] != in[i*8 + 4] + || out[i*8 + 5] != in[i*8 + 5] + || out[i*8 + 6] != in[i*8 + 6] + || out[i*8 + 7] != in[i*8 + 7] + || ia[i] != 7) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = in[i*4]; + out[i*4 + 1] = in[i*4 + 1]; + out[i*4 + 2] = in[i*4 + 2]; + out[i*4 + 3] = in[i*4 + 3]; + + ia[i] = 12; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != in[i*4] + || out[i*4 + 1] != in[i*4 + 1] + || out[i*4 + 2] != in[i*4 + 2] + || out[i*4 + 3] != in[i*4 + 3] + || ia[i] != 12) + abort (); + } + + for (i = 0; i < N/2; i++) + { + out[i*16] = in[i*16]; + out[i*16 + 1] = in[i*16 + 1]; + out[i*16 + 2] = in[i*16 + 2]; + out[i*16 + 3] = in[i*16 + 3]; + out[i*16 + 4] = in[i*16 + 4]; + out[i*16 + 5] = in[i*16 + 5]; + out[i*16 + 6] = in[i*16 + 6]; + out[i*16 + 7] = in[i*16 + 7]; + out[i*16 + 8] = in[i*16 + 8]; + out[i*16 + 9] = in[i*16 + 9]; + out[i*16 + 10] = in[i*16 + 10]; + out[i*16 + 11] = in[i*16 + 11]; + out[i*16 + 12] = in[i*16 + 12]; + out[i*16 + 13] = in[i*16 + 13]; + out[i*16 + 14] = in[i*16 + 14]; + out[i*16 + 15] = in[i*16 + 15]; + + ia[i] = 21; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*16] != in[i*16] + || out[i*16 + 1] != in[i*16 + 1] + || out[i*16 + 2] != in[i*16 + 2] + || out[i*16 + 3] != in[i*16 + 3] + || out[i*16 + 4] != in[i*16 + 4] + || out[i*16 + 5] != in[i*16 + 5] + || out[i*16 + 6] != in[i*16 + 6] + || out[i*16 + 7] != in[i*16 + 7] + || out[i*16 + 8] != in[i*16 + 8] + || out[i*16 + 9] != in[i*16 + 9] + || out[i*16 + 10] != in[i*16 + 10] + || out[i*16 + 11] != in[i*16 + 11] + || out[i*16 + 12] != in[i*16 + 12] + || out[i*16 + 13] != in[i*16 + 13] + || out[i*16 + 14] != in[i*16 + 14] + || out[i*16 + 15] != in[i*16 + 15] + || ia[i] != 21) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-5.c b/gcc/testsuite/gcc.dg/vect/slp-5.c new file mode 100644 index 000000000..b99cadf13 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-5.c @@ -0,0 +1,126 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int +main1 () +{ + int i; + unsigned int out[N*8]; + unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + unsigned short ia[N]; + unsigned int ib[N*2]; + + /* Multiple types with SLP of the smaller type. */ + for (i = 0; i < N; i++) + { + out[i*8] = in[i*8]; + out[i*8 + 1] = in[i*8 + 1]; + out[i*8 + 2] = in[i*8 + 2]; + out[i*8 + 3] = in[i*8 + 3]; + out[i*8 + 4] = in[i*8 + 4]; + out[i*8 + 5] = in[i*8 + 5]; + out[i*8 + 6] = in[i*8 + 6]; + out[i*8 + 7] = in[i*8 + 7]; + + ia[i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + || out[i*8 + 1] != in[i*8 + 1] + || out[i*8 + 2] != in[i*8 + 2] + || out[i*8 + 3] != in[i*8 + 3] + || out[i*8 + 4] != in[i*8 + 4] + || out[i*8 + 5] != in[i*8 + 5] + || out[i*8 + 6] != in[i*8 + 6] + || out[i*8 + 7] != in[i*8 + 7] + || ia[i] != 7) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = in[i*4]; + out[i*4 + 1] = in[i*4 + 1]; + out[i*4 + 2] = in[i*4 + 2]; + out[i*4 + 3] = in[i*4 + 3]; + + ib[i] = 12; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != in[i*4] + || out[i*4 + 1] != in[i*4 + 1] + || out[i*4 + 2] != in[i*4 + 2] + || out[i*4 + 3] != in[i*4 + 3] + || ib[i] != 12) + abort (); + } + + for (i = 0; i < N/2; i++) + { + out[i*16] = in[i*16]; + out[i*16 + 1] = in[i*16 + 1]; + out[i*16 + 2] = in[i*16 + 2]; + out[i*16 + 3] = in[i*16 + 3]; + out[i*16 + 4] = in[i*16 + 4]; + out[i*16 + 5] = in[i*16 + 5]; + out[i*16 + 6] = in[i*16 + 6]; + out[i*16 + 7] = in[i*16 + 7]; + out[i*16 + 8] = in[i*16 + 8]; + out[i*16 + 9] = in[i*16 + 9]; + out[i*16 + 10] = in[i*16 + 10]; + out[i*16 + 11] = in[i*16 + 11]; + out[i*16 + 12] = in[i*16 + 12]; + out[i*16 + 13] = in[i*16 + 13]; + out[i*16 + 14] = in[i*16 + 14]; + out[i*16 + 15] = in[i*16 + 15]; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*16] != in[i*16] + || out[i*16 + 1] != in[i*16 + 1] + || out[i*16 + 2] != in[i*16 + 2] + || out[i*16 + 3] != in[i*16 + 3] + || out[i*16 + 4] != in[i*16 + 4] + || out[i*16 + 5] != in[i*16 + 5] + || out[i*16 + 6] != in[i*16 + 6] + || out[i*16 + 7] != in[i*16 + 7] + || out[i*16 + 8] != in[i*16 + 8] + || out[i*16 + 9] != in[i*16 + 9] + || out[i*16 + 10] != in[i*16 + 10] + || out[i*16 + 11] != in[i*16 + 11] + || out[i*16 + 12] != in[i*16 + 12] + || out[i*16 + 13] != in[i*16 + 13] + || out[i*16 + 14] != in[i*16 + 14] + || out[i*16 + 15] != in[i*16 + 15]) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-6.c b/gcc/testsuite/gcc.dg/vect/slp-6.c new file mode 100644 index 000000000..e8d007b02 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-6.c @@ -0,0 +1,122 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned int in2[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +int +main1 () +{ + int i; + unsigned short out[N*8]; + unsigned int out2[N*8]; + + for (i = 0; i < N; i++) + { + out[i*8] = in[i*8] + 5; + out[i*8 + 1] = in[i*8 + 1] + 6; + out[i*8 + 2] = in[i*8 + 2] + 7; + out[i*8 + 3] = in[i*8 + 3] + 8; + out[i*8 + 4] = in[i*8 + 4] + 9; + out[i*8 + 5] = in[i*8 + 5] + 10; + out[i*8 + 6] = in[i*8 + 6] + 11; + out[i*8 + 7] = in[i*8 + 7] + 12; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + 5 + || out[i*8 + 1] != in[i*8 + 1] + 6 + || out[i*8 + 2] != in[i*8 + 2] + 7 + || out[i*8 + 3] != in[i*8 + 3] + 8 + || out[i*8 + 4] != in[i*8 + 4] + 9 + || out[i*8 + 5] != in[i*8 + 5] + 10 + || out[i*8 + 6] != in[i*8 + 6] + 11 + || out[i*8 + 7] != in[i*8 + 7] + 12) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = in[i*4] + 2; + out[i*4 + 1] = in[i*4 + 1] + 2; + out[i*4 + 2] = in[i*4 + 2] + 1; + out[i*4 + 3] = in[i*4 + 3] + 3; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != in[i*4] + 2 + || out[i*4 + 1] != in[i*4 + 1] + 2 + || out[i*4 + 2] != in[i*4 + 2] + 1 + || out[i*4 + 3] != in[i*4 + 3] + 3) + abort (); + } + + for (i = 0; i < N/2; i++) + { + out2[i*16] = in2[i*16] * 2; + out2[i*16 + 1] = in2[i*16 + 1] * 3; + out2[i*16 + 2] = in2[i*16 + 2] * 4; + out2[i*16 + 3] = in2[i*16 + 3] * 3; + out2[i*16 + 4] = in2[i*16 + 4] * 2; + out2[i*16 + 5] = in2[i*16 + 5] * 3; + out2[i*16 + 6] = in2[i*16 + 6] * 2; + out2[i*16 + 7] = in2[i*16 + 7] * 4; + out2[i*16 + 8] = in2[i*16 + 8] * 2; + out2[i*16 + 9] = in2[i*16 + 9] * 5; + out2[i*16 + 10] = in2[i*16 + 10] * 2; + out2[i*16 + 11] = in2[i*16 + 11] * 3; + out2[i*16 + 12] = in2[i*16 + 12] * 4; + out2[i*16 + 13] = in2[i*16 + 13] * 4; + out2[i*16 + 14] = in2[i*16 + 14] * 3; + out2[i*16 + 15] = in2[i*16 + 15] * 2; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out2[i*16] != in2[i*16] * 2 + || out2[i*16 + 1] != in2[i*16 + 1] * 3 + || out2[i*16 + 2] != in2[i*16 + 2] * 4 + || out2[i*16 + 3] != in2[i*16 + 3] * 3 + || out2[i*16 + 4] != in2[i*16 + 4] * 2 + || out2[i*16 + 5] != in2[i*16 + 5] * 3 + || out2[i*16 + 6] != in2[i*16 + 6] * 2 + || out2[i*16 + 7] != in2[i*16 + 7] * 4 + || out2[i*16 + 8] != in2[i*16 + 8] * 2 + || out2[i*16 + 9] != in2[i*16 + 9] * 5 + || out2[i*16 + 10] != in2[i*16 + 10] * 2 + || out2[i*16 + 11] != in2[i*16 + 11] * 3 + || out2[i*16 + 12] != in2[i*16 + 12] * 4 + || out2[i*16 + 13] != in2[i*16 + 13] * 4 + || out2[i*16 + 14] != in2[i*16 + 14] * 3 + || out2[i*16 + 15] != in2[i*16 + 15] * 2) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {target vect_int_mult} } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {target { ! { vect_int_mult } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" {target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" {target { ! { vect_int_mult } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-7.c b/gcc/testsuite/gcc.dg/vect/slp-7.c new file mode 100644 index 000000000..9e7ce8c8c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-7.c @@ -0,0 +1,128 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int in[N*8] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned short in2[N*16] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +int +main1 () +{ + int i; + unsigned int out[N*8], ia[N*2]; + unsigned short sa[N], out2[N*16]; + + for (i = 0; i < N; i++) + { + out[i*8] = in[i*8] + 5; + out[i*8 + 1] = in[i*8 + 1] + 6; + out[i*8 + 2] = in[i*8 + 2] + 7; + out[i*8 + 3] = in[i*8 + 3] + 8; + out[i*8 + 4] = in[i*8 + 4] + 9; + out[i*8 + 5] = in[i*8 + 5] + 10; + out[i*8 + 6] = in[i*8 + 6] + 11; + out[i*8 + 7] = in[i*8 + 7] + 12; + + ia[i] = in[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != in[i*8] + 5 + || out[i*8 + 1] != in[i*8 + 1] + 6 + || out[i*8 + 2] != in[i*8 + 2] + 7 + || out[i*8 + 3] != in[i*8 + 3] + 8 + || out[i*8 + 4] != in[i*8 + 4] + 9 + || out[i*8 + 5] != in[i*8 + 5] + 10 + || out[i*8 + 6] != in[i*8 + 6] + 11 + || out[i*8 + 7] != in[i*8 + 7] + 12 + || ia[i] != in[i]) + abort (); + } + + for (i = 0; i < N*2; i++) + { + out[i*4] = in[i*4] + 1; + out[i*4 + 1] = in[i*4 + 1] + 2; + out[i*4 + 2] = in[i*4 + 2] + 3; + out[i*4 + 3] = in[i*4 + 3] + 4; + + ia[i] = in[i]; + } + + /* check results: */ + for (i = 0; i < N*2; i++) + { + if (out[i*4] != in[i*4] + 1 + || out[i*4 + 1] != in[i*4 + 1] + 2 + || out[i*4 + 2] != in[i*4 + 2] + 3 + || out[i*4 + 3] != in[i*4 + 3] + 4 + || ia[i] != in[i]) + abort (); + } + + for (i = 0; i < N; i++) + { + out2[i*16] = in2[i*16] * 2; + out2[i*16 + 1] = in2[i*16 + 1] * 3; + out2[i*16 + 2] = in2[i*16 + 2] * 4; + out2[i*16 + 3] = in2[i*16 + 3] * 3; + out2[i*16 + 4] = in2[i*16 + 4] * 2; + out2[i*16 + 5] = in2[i*16 + 5] * 3; + out2[i*16 + 6] = in2[i*16 + 6] * 2; + out2[i*16 + 7] = in2[i*16 + 7] * 4; + out2[i*16 + 8] = in2[i*16 + 8] * 2; + out2[i*16 + 9] = in2[i*16 + 9] * 5; + out2[i*16 + 10] = in2[i*16 + 10] * 2; + out2[i*16 + 11] = in2[i*16 + 11] * 3; + out2[i*16 + 12] = in2[i*16 + 12] * 4; + out2[i*16 + 13] = in2[i*16 + 13] * 4; + out2[i*16 + 14] = in2[i*16 + 14] * 3; + out2[i*16 + 15] = in2[i*16 + 15] * 2; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out2[i*16] != in2[i*16] * 2 + || out2[i*16 + 1] != in2[i*16 + 1] * 3 + || out2[i*16 + 2] != in2[i*16 + 2] * 4 + || out2[i*16 + 3] != in2[i*16 + 3] * 3 + || out2[i*16 + 4] != in2[i*16 + 4] * 2 + || out2[i*16 + 5] != in2[i*16 + 5] * 3 + || out2[i*16 + 6] != in2[i*16 + 6] * 2 + || out2[i*16 + 7] != in2[i*16 + 7] * 4 + || out2[i*16 + 8] != in2[i*16 + 8] * 2 + || out2[i*16 + 9] != in2[i*16 + 9] * 5 + || out2[i*16 + 10] != in2[i*16 + 10] * 2 + || out2[i*16 + 11] != in2[i*16 + 11] * 3 + || out2[i*16 + 12] != in2[i*16 + 12] * 4 + || out2[i*16 + 13] != in2[i*16 + 13] * 4 + || out2[i*16 + 14] != in2[i*16 + 14] * 3 + || out2[i*16 + 15] != in2[i*16 + 15] * 2) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target vect_short_mult } } }*/ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { ! { vect_short_mult } } } } }*/ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target vect_short_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { ! { vect_short_mult } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-8.c b/gcc/testsuite/gcc.dg/vect/slp-8.c new file mode 100644 index 000000000..76db4e1c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-8.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +int main1 () +{ + int i; + float fa[N]; + + /* int -> float */ + for (i = 0; i < N/4; i++) + { + fa[4*i] = (float) ib[4*i]; + fa[4*i + 1] = (float) ib[4*i + 1]; + fa[4*i + 2] = (float) ib[4*i + 2]; + fa[4*i + 3] = (float) ib[4*i + 3]; + } + + /* check results: */ + for (i = 0; i < N/4; i++) + { + if (fa[4*i] != (float) ib[4*i] + || fa[4*i + 1] != (float) ib[4*i + 1] + || fa[4*i + 2] != (float) ib[4*i + 2] + || fa[4*i + 3] != (float) ib[4*i + 3]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target powerpc*-*-* i?86-*-* x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target powerpc*-*-* i?86-*-* x86_64-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-9.c b/gcc/testsuite/gcc.dg/vect/slp-9.c new file mode 100644 index 000000000..7e1ede4b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-9.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int result[N]; + +/* short->int widening-mult */ +int +foo1(int len) { + int i; + + for (i=0; i<len/2; i++) { + result[2*i] = X[2*i] * Y[2*i]; + result[2*i+1] = X[2*i+1] * Y[2*i+1]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (result[i] != X[i] * Y[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_hi_to_si } } }*/ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-1.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-1.c new file mode 100644 index 000000000..b52838197 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-1.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +__attribute__ ((noinline)) int +main1 () +{ + int i; + unsigned short sout[N*8]; + unsigned int iout[N*8]; + + for (i = 0; i < N; i++) + { + sout[i*4] = 8; + sout[i*4 + 1] = 18; + sout[i*4 + 2] = 28; + sout[i*4 + 3] = 38; + + iout[i*4] = 8; + iout[i*4 + 1] = 18; + iout[i*4 + 2] = 28; + iout[i*4 + 3] = 38; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (sout[i*4] != 8 + || sout[i*4 + 1] != 18 + || sout[i*4 + 2] != 28 + || sout[i*4 + 3] != 38 + || iout[i*4] != 8 + || iout[i*4 + 1] != 18 + || iout[i*4 + 2] != 28 + || iout[i*4 + 3] != 38) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-10.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-10.c new file mode 100644 index 000000000..3dd6b84e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-10.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +struct s +{ + unsigned char a; + unsigned char b; +}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + struct s out[N*4]; + + for (i = 0; i < N*4; i++) + { + out[i].a = (unsigned char) in[i*2] + 1; + out[i].b = (unsigned char) in[i*2 + 1] + 2; + } + + /* check results: */ + for (i = 0; i < N*4; i++) + { + if (out[i].a != (unsigned char) in[i*2] + 1 + || out[i].b != (unsigned char) in[i*2 + 1] + 2) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c new file mode 100644 index 000000000..602517bfc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 18 + +struct s +{ + int a; + int b; + int c; +}; + +char in[N*3] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + struct s out[N]; + + for (i = 0; i < N; i++) + { + out[i].a = (int) in[i*3] + 1; + out[i].b = (int) in[i*3 + 1] + 2; + out[i].c = (int) in[i*3 + 2] + 3; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i].a != (int) in[i*3] + 1 + || out[i].b != (int) in[i*3 + 1] + 2 + || out[i].c != (int) in[i*3 + 2] + 3) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-12.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-12.c new file mode 100644 index 000000000..e9a2c6d4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-12.c @@ -0,0 +1,67 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +__attribute__ ((noinline)) int +main1 () +{ + int i; + unsigned short sout[N*8]; + unsigned int iout[N*8]; + unsigned char cout[N*8]; + + for (i = 0; i < N; i++) + { + sout[i*4] = 8; + sout[i*4 + 1] = 18; + sout[i*4 + 2] = 28; + sout[i*4 + 3] = 38; + + iout[i*4] = 8; + iout[i*4 + 1] = 18; + iout[i*4 + 2] = 28; + iout[i*4 + 3] = 38; + + cout[i*4] = 1; + cout[i*4 + 1] = 2; + cout[i*4 + 2] = 3; + cout[i*4 + 3] = 4; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (sout[i*4] != 8 + || sout[i*4 + 1] != 18 + || sout[i*4 + 2] != 28 + || sout[i*4 + 3] != 38 + || iout[i*4] != 8 + || iout[i*4 + 1] != 18 + || iout[i*4 + 2] != 28 + || iout[i*4 + 3] != 38 + || cout[i*4] != 1 + || cout[i*4 + 1] != 2 + || cout[i*4 + 2] != 3 + || cout[i*4 + 3] != 4) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-2.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-2.c new file mode 100644 index 000000000..3c04b6d21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-2.c @@ -0,0 +1,83 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-xfail-run-if "PR rtl-optimization/46603" { sparc*-*-* && { ilp32 && gas } } } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +__attribute__ ((noinline)) int +main1 (unsigned short a0, unsigned short a1, unsigned short a2, + unsigned short a3, unsigned short a4, unsigned short a5, + unsigned short a6, unsigned short a7, unsigned short a8, + unsigned short a9, unsigned short a10, unsigned short a11, + unsigned short a12, unsigned short a13, unsigned short a14, + unsigned short a15, unsigned char b0, unsigned char b1) +{ + int i; + unsigned short out[N*16]; + unsigned char out2[N*16]; + + for (i = 0; i < N; i++) + { + out[i*16] = a8; + out[i*16 + 1] = a7; + out[i*16 + 2] = a1; + out[i*16 + 3] = a2; + out[i*16 + 4] = a8; + out[i*16 + 5] = a5; + out[i*16 + 6] = a5; + out[i*16 + 7] = a4; + out[i*16 + 8] = a12; + out[i*16 + 9] = a13; + out[i*16 + 10] = a14; + out[i*16 + 11] = a15; + out[i*16 + 12] = a6; + out[i*16 + 13] = a9; + out[i*16 + 14] = a0; + out[i*16 + 15] = a7; + + out2[i*2] = b1; + out2[i*2+1] = b0; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*16] != a8 + || out[i*16 + 1] != a7 + || out[i*16 + 2] != a1 + || out[i*16 + 3] != a2 + || out[i*16 + 4] != a8 + || out[i*16 + 5] != a5 + || out[i*16 + 6] != a5 + || out[i*16 + 7] != a4 + || out[i*16 + 8] != a12 + || out[i*16 + 9] != a13 + || out[i*16 + 10] != a14 + || out[i*16 + 11] != a15 + || out[i*16 + 12] != a6 + || out[i*16 + 13] != a9 + || out[i*16 + 14] != a0 + || out[i*16 + 15] != a7 + || out2[i*2] != b1 + || out2[i*2 + 1] != b0) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,20,21); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-3.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-3.c new file mode 100644 index 000000000..635344893 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-3.c @@ -0,0 +1,93 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned char in2[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + unsigned int out[N*8]; + unsigned char out2[N*8]; + + for (i = 0; i < N/2; i++) + { + out[i*8] = in[i*8] + 5; + out[i*8 + 1] = in[i*8 + 1] + 6; + out[i*8 + 2] = in[i*8 + 2] + 7; + out[i*8 + 3] = in[i*8 + 3] + 8; + out[i*8 + 4] = in[i*8 + 4] + 9; + out[i*8 + 5] = in[i*8 + 5] + 10; + out[i*8 + 6] = in[i*8 + 6] + 11; + out[i*8 + 7] = in[i*8 + 7] + 12; + + out2[i*16] = in2[i*16] + 2; + out2[i*16 + 1] = in2[i*16 + 1] + 3; + out2[i*16 + 2] = in2[i*16 + 2] + 4; + out2[i*16 + 3] = in2[i*16 + 3] + 3; + out2[i*16 + 4] = in2[i*16 + 4] + 2; + out2[i*16 + 5] = in2[i*16 + 5] + 3; + out2[i*16 + 6] = in2[i*16 + 6] + 2; + out2[i*16 + 7] = in2[i*16 + 7] + 4; + out2[i*16 + 8] = in2[i*16 + 8] + 2; + out2[i*16 + 9] = in2[i*16 + 9] + 5; + out2[i*16 + 10] = in2[i*16 + 10] + 2; + out2[i*16 + 11] = in2[i*16 + 11] + 3; + out2[i*16 + 12] = in2[i*16 + 12] + 4; + out2[i*16 + 13] = in2[i*16 + 13] + 4; + out2[i*16 + 14] = in2[i*16 + 14] + 3; + out2[i*16 + 15] = in2[i*16 + 15] + 2; + + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (out[i*8] != in[i*8] + 5 + || out[i*8 + 1] != in[i*8 + 1] + 6 + || out[i*8 + 2] != in[i*8 + 2] + 7 + || out[i*8 + 3] != in[i*8 + 3] + 8 + || out[i*8 + 4] != in[i*8 + 4] + 9 + || out[i*8 + 5] != in[i*8 + 5] + 10 + || out[i*8 + 6] != in[i*8 + 6] + 11 + || out[i*8 + 7] != in[i*8 + 7] + 12 + || out2[i*16] != in2[i*16] + 2 + || out2[i*16 + 1] != in2[i*16 + 1] + 3 + || out2[i*16 + 2] != in2[i*16 + 2] + 4 + || out2[i*16 + 3] != in2[i*16 + 3] + 3 + || out2[i*16 + 4] != in2[i*16 + 4] + 2 + || out2[i*16 + 5] != in2[i*16 + 5] + 3 + || out2[i*16 + 6] != in2[i*16 + 6] + 2 + || out2[i*16 + 7] != in2[i*16 + 7] + 4 + || out2[i*16 + 8] != in2[i*16 + 8] + 2 + || out2[i*16 + 9] != in2[i*16 + 9] + 5 + || out2[i*16 + 10] != in2[i*16 + 10] + 2 + || out2[i*16 + 11] != in2[i*16 + 11] + 3 + || out2[i*16 + 12] != in2[i*16 + 12] + 4 + || out2[i*16 + 13] != in2[i*16 + 13] + 4 + || out2[i*16 + 14] != in2[i*16 + 14] + 3 + || out2[i*16 + 15] != in2[i*16 + 15] + 2) + + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { sparc*-*-* && ilp32 } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { xfail { sparc*-*-* && ilp32 } }} } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-4.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-4.c new file mode 100644 index 000000000..a13f08d3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-4.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + int out[N*8]; + + for (i = 0; i < N; i++) + { + out[i*8] = (int) in[i*8] + 1; + out[i*8 + 1] = (int) in[i*8 + 1] + 2; + out[i*8 + 2] = (int) in[i*8 + 2] + 3; + out[i*8 + 3] = (int) in[i*8 + 3] + 4; + out[i*8 + 4] = (int) in[i*8 + 4] + 5; + out[i*8 + 5] = (int) in[i*8 + 5] + 6; + out[i*8 + 6] = (int) in[i*8 + 6] + 7; + out[i*8 + 7] = (int) in[i*8 + 7] + 8; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (int) in[i*8] + 1 + || out[i*8 + 1] != (int) in[i*8 + 1] + 2 + || out[i*8 + 2] != (int) in[i*8 + 2] + 3 + || out[i*8 + 3] != (int) in[i*8 + 3] + 4 + || out[i*8 + 4] != (int) in[i*8 + 4] + 5 + || out[i*8 + 5] != (int) in[i*8 + 5] + 6 + || out[i*8 + 6] != (int) in[i*8 + 6] + 7 + || out[i*8 + 7] != (int) in[i*8 + 7] + 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-5.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-5.c new file mode 100644 index 000000000..da4527646 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-5.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +short in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + int out[N*8]; + + for (i = 0; i < N; i++) + { + out[i*8] = (short) in[i*8] + 1; + out[i*8 + 1] = (short) in[i*8 + 1] + 2; + out[i*8 + 2] = (short) in[i*8 + 2] + 3; + out[i*8 + 3] = (short) in[i*8 + 3] + 4; + out[i*8 + 4] = (short) in[i*8 + 4] + 5; + out[i*8 + 5] = (short) in[i*8 + 5] + 6; + out[i*8 + 6] = (short) in[i*8 + 6] + 7; + out[i*8 + 7] = (short) in[i*8 + 7] + 8; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (short) in[i*8] + 1 + || out[i*8 + 1] != (short) in[i*8 + 1] + 2 + || out[i*8 + 2] != (short) in[i*8 + 2] + 3 + || out[i*8 + 3] != (short) in[i*8 + 3] + 4 + || out[i*8 + 4] != (short) in[i*8 + 4] + 5 + || out[i*8 + 5] != (short) in[i*8 + 5] + 6 + || out[i*8 + 6] != (short) in[i*8 + 6] + 7 + || out[i*8 + 7] != (short) in[i*8 + 7] + 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-6.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-6.c new file mode 100644 index 000000000..38f4f5d1f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-6.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + unsigned char out[N*8]; + + for (i = 0; i < N; i++) + { + out[i*8] = (unsigned char) in[i*8] + 1; + out[i*8 + 1] = (unsigned char) in[i*8 + 1] + 2; + out[i*8 + 2] = (unsigned char) in[i*8 + 2] + 3; + out[i*8 + 3] = (unsigned char) in[i*8 + 3] + 4; + out[i*8 + 4] = (unsigned char) in[i*8 + 4] + 5; + out[i*8 + 5] = (unsigned char) in[i*8 + 5] + 6; + out[i*8 + 6] = (unsigned char) in[i*8 + 6] + 7; + out[i*8 + 7] = (unsigned char) in[i*8 + 7] + 8; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (unsigned char) in[i*8] + 1 + || out[i*8 + 1] != (unsigned char) in[i*8 + 1] + 2 + || out[i*8 + 2] != (unsigned char) in[i*8 + 2] + 3 + || out[i*8 + 3] != (unsigned char) in[i*8 + 3] + 4 + || out[i*8 + 4] != (unsigned char) in[i*8 + 4] + 5 + || out[i*8 + 5] != (unsigned char) in[i*8 + 5] + 6 + || out[i*8 + 6] != (unsigned char) in[i*8 + 6] + 7 + || out[i*8 + 7] != (unsigned char) in[i*8 + 7] + 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-7.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-7.c new file mode 100644 index 000000000..112db6b72 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-7.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +char in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + int out[N*8]; + + for (i = 0; i < N; i++) + { + out[i*8] = (int) in[i*8] + 1; + out[i*8 + 1] = (int) in[i*8 + 1] + 2; + out[i*8 + 2] = (int) in[i*8 + 2] + 3; + out[i*8 + 3] = (int) in[i*8 + 3] + 4; + out[i*8 + 4] = (int) in[i*8 + 4] + 5; + out[i*8 + 5] = (int) in[i*8 + 5] + 6; + out[i*8 + 6] = (int) in[i*8 + 6] + 7; + out[i*8 + 7] = (int) in[i*8 + 7] + 8; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (out[i*8] != (int) in[i*8] + 1 + || out[i*8 + 1] != (int) in[i*8 + 1] + 2 + || out[i*8 + 2] != (int) in[i*8 + 2] + 3 + || out[i*8 + 3] != (int) in[i*8 + 3] + 4 + || out[i*8 + 4] != (int) in[i*8 + 4] + 5 + || out[i*8 + 5] != (int) in[i*8 + 5] + 6 + || out[i*8 + 6] != (int) in[i*8 + 6] + 7 + || out[i*8 + 7] != (int) in[i*8 + 7] + 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-8.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-8.c new file mode 100644 index 000000000..bd89c130d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-8.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +char in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + int out[N*8]; + + for (i = 0; i < N*4; i++) + { + out[i*2] = (int) in[i*2] + 1; + out[i*2 + 1] = (int) in[i*2 + 1] + 2; + } + + /* check results: */ + for (i = 0; i < N*4; i++) + { + if (out[i*2] != (int) in[i*2] + 1 + || out[i*2 + 1] != (int) in[i*2 + 1] + 2) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-9.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-9.c new file mode 100644 index 000000000..f0cf32933 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-9.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + unsigned char out[N*8]; + + for (i = 0; i < N*4; i++) + { + out[i*2] = (unsigned char) in[i*2] + 1; + out[i*2 + 1] = (unsigned char) in[i*2 + 1] + 2; + } + + /* check results: */ + for (i = 0; i < N*4; i++) + { + if (out[i*2] != (unsigned char) in[i*2] + 1 + || out[i*2 + 1] != (unsigned char) in[i*2 + 1] + 2) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c new file mode 100644 index 000000000..756cf0b11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c @@ -0,0 +1,63 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M20 23 +#define M01 1322 +#define M11 13 +#define M21 27271 +#define M02 74 +#define M12 191 +#define M22 500 + +#define N 16 + +void foo (unsigned int *__restrict__ pInput, unsigned int *__restrict__ pOutput) +{ + unsigned int i, a, b, c; + + for (i = 0; i < N / 3; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + + *pOutput++ = M00 * a + M01 * b + M02 * c; + *pOutput++ = M10 * a + M11 * b + M12 * c; + *pOutput++ = M20 * a + M21 * b + M22 * c; + } +} + +int main (int argc, const char* argv[]) +{ + unsigned int input[N], output[N], i; + unsigned int check_results[N] = {1470, 395, 28271, 5958, 1655, 111653, 10446, 2915, 195035, 14934, 4175, 278417, 19422, 5435, 361799, 0}; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + output[i] = 0; + __asm__ volatile (""); + } + + foo (input, output); + + for (i = 0; i < N; i++) + { + if (output[i] != check_results[i]) + abort (); + __asm__ volatile (""); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-2.c b/gcc/testsuite/gcc.dg/vect/slp-perm-2.c new file mode 100644 index 000000000..1bc95e2e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-2.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M01 1322 +#define M11 13 +#define M02 74 +#define M12 191 + +#define N 16 + +void foo (unsigned int *__restrict__ pInput, unsigned int *__restrict__ pOutput) +{ + unsigned int i, a, b; + + for (i = 0; i < N / 2; i++) + { + a = *pInput++; + b = *pInput++; + + *pOutput++ = M00 * a + M01 * b; + *pOutput++ = M10 * a + M11 * b; + } +} + +int main (int argc, const char* argv[]) +{ + unsigned int input[N], output[N], i; + unsigned int check_results[N] = {1322, 13, 4166, 471, 7010, 929, 9854, 1387, 12698, 1845, 15542, 2303, 18386, 2761, 21230, 3219}; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + output[i] = 0; + __asm__ volatile (""); + } + + foo (input, output); + + for (i = 0; i < N; i++) + { + if (output[i] != check_results[i]) + abort (); + __asm__ volatile (""); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-3.c b/gcc/testsuite/gcc.dg/vect/slp-perm-3.c new file mode 100644 index 000000000..88c02fba6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-3.c @@ -0,0 +1,73 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M20 23 +#define M30 237 +#define M01 1322 +#define M11 13 +#define M21 27271 +#define M31 2280 +#define M02 74 +#define M12 191 +#define M22 500 +#define M32 111 +#define M03 134 +#define M13 117 +#define M23 11 +#define M33 771 + +#define N 16 + +void foo (unsigned int *__restrict__ pInput, unsigned int *__restrict__ pOutput) +{ + unsigned int i, a, b, c, d; + + for (i = 0; i < N / 4; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + d = *pInput++; + + *pOutput++ = M00 * a + M01 * b + M02 * c + M03 * d; + *pOutput++ = M10 * a + M11 * b + M12 * c + M13 * d; + *pOutput++ = M20 * a + M21 * b + M22 * c + M23 * d; + *pOutput++ = M30 * a + M31 * b + M32 * c + M33 * d; + } +} + +int main (int argc, const char* argv[]) +{ + unsigned int input[N], output[N], i; + unsigned int check_results[N] = {1872, 746, 28304, 4815, 8392, 2894, 139524, 18411, 14912, 5042, 250744, 32007, 21432, 7190, 361964, 45603}; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + output[i] = 0; + __asm__ volatile (""); + } + + foo (input, output); + + for (i = 0; i < N; i++) + { + if (output[i] != check_results[i]) + abort (); + __asm__ volatile (""); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-4.c b/gcc/testsuite/gcc.dg/vect/slp-perm-4.c new file mode 100644 index 000000000..239461a0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-4.c @@ -0,0 +1,87 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M20 23 +#define M30 237 +#define M40 437 + +#define M01 1322 +#define M11 13 +#define M21 27271 +#define M31 2280 +#define M41 284 + +#define M02 74 +#define M12 191 +#define M22 500 +#define M32 111 +#define M42 1114 + +#define M03 134 +#define M13 117 +#define M23 11 +#define M33 771 +#define M43 71 + +#define M04 334 +#define M14 147 +#define M24 115 +#define M34 7716 +#define M44 16 + +#define N 16 + +void foo (unsigned int *__restrict__ pInput, unsigned int *__restrict__ pOutput) +{ + unsigned int i, a, b, c, d, e; + + for (i = 0; i < N / 5; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + d = *pInput++; + e = *pInput++; + + *pOutput++ = M00 * a + M01 * b + M02 * c + M03 * d + M04 * e; + *pOutput++ = M10 * a + M11 * b + M12 * c + M13 * d + M14 * e; + *pOutput++ = M20 * a + M21 * b + M22 * c + M23 * d + M24 * e; + *pOutput++ = M30 * a + M31 * b + M32 * c + M33 * d + M34 * e; + *pOutput++ = M40 * a + M41 * b + M42 * c + M43 * d + M44 * e; + } +} + +int main (int argc, const char* argv[]) +{ + unsigned int input[N], output[N], i; + unsigned int check_results[N] = {3208, 1334, 28764, 35679, 2789, 13028, 4754, 168364, 91254, 12399, 22848, 8174, 307964, 146829, 22009, 0}; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + if (input[i] > 200) + abort(); + output[i] = 0; + __asm__ volatile (""); + } + + foo (input, output); + + for (i = 0; i < N; i++) + if (output[i] != check_results[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c new file mode 100644 index 000000000..f8ee4c10e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c @@ -0,0 +1,79 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M20 23 +#define M01 1322 +#define M11 13 +#define M21 27271 +#define M02 74 +#define M12 191 +#define M22 500 + +#define K00 405 +#define K10 112 +#define K01 4322 +#define K11 135 + +#define N 16 + +void foo (int *__restrict__ pInput, int *__restrict__ pOutput, + int *__restrict__ pInput2, int *__restrict__ pOutput2) +{ + int i, a, b, c, d, e; + + for (i = 0; i < N / 3; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + + d = *pInput2++; + e = *pInput2++; + + *pOutput++ = M00 * a + M01 * b + M02 * c; + *pOutput++ = M10 * a + M11 * b + M12 * c; + *pOutput++ = M20 * a + M21 * b + M22 * c; + + *pOutput2++ = K00 * d + K01 * e; + *pOutput2++ = K10 * d + K11 * e; + } +} + +int main (int argc, const char* argv[]) +{ + int input[N], output[N], i; + int check_results[N] = {1470, 395, 28271, 5958, 1655, 111653, 10446, 2915, 195035, 14934, 4175, 278417, 19422, 5435, 361799, 0}; + int input2[N], output2[N]; + int check_results2[N] = {4322, 135, 13776, 629, 23230, 1123, 32684, 1617, 42138, 2111, 0, 0, 0, 0, 0, 0}; + + check_vect (); + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + input2[i] = i%256; + output[i] = 0; + output2[i] = 0; + __asm__ volatile (""); + } + + foo (input, output, input2, output2); + + for (i = 0; i < N; i++) + if (output[i] != check_results[i] || output2[i] != check_results2[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_perm } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c new file mode 100644 index 000000000..a2843a04b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c @@ -0,0 +1,77 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M20 23 +#define M01 1322 +#define M11 13 +#define M21 27271 +#define M02 74 +#define M12 191 +#define M22 500 + +#define K00 405 +#define K10 112 +#define K01 4322 +#define K11 135 + +#define N 16 + +void foo (int *__restrict__ pInput, int *__restrict__ pOutput, + int *__restrict__ pInput2, int *__restrict__ pOutput2) +{ + int i, a, b, c, d, e; + + for (i = 0; i < N / 3; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + + d = *pInput2++; + e = *pInput2++; + + *pOutput++ = M00 * a + M01 * b + M02 * c; + *pOutput++ = M10 * a + M11 * b + M12 * c; + *pOutput++ = M20 * a + M21 * b + M22 * c; + + /* Regular SLP - no permutation required. */ + *pOutput2++ = K00 * d; + *pOutput2++ = K10 * e; + } +} + +int main (int argc, const char* argv[]) +{ + int input[N], output[N], i; + int check_results[N] = {1470, 395, 28271, 5958, 1655, 111653, 10446, 2915, 195035, 14934, 4175, 278417, 19422, 5435, 361799, 0}; + int input2[N], output2[N]; + int check_results2[N] = {0, 112, 810, 336, 1620, 560, 2430, 784, 3240, 1008, 0, 0, 0, 0, 0, 0}; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + input2[i] = i%256; + output[i] = 0; + output2[i] = 0; + __asm__ volatile (""); + } + + foo (input, output, input2, output2); + + for (i = 0; i < N; i++) + if (output[i] != check_results[i] || output2[i] != check_results2[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_perm } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c new file mode 100644 index 000000000..6291096f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c @@ -0,0 +1,77 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define M00 100 +#define M10 216 +#define M20 23 +#define M01 1322 +#define M11 13 +#define M21 27271 +#define M02 74 +#define M12 191 +#define M22 500 + +#define K00 405 +#define K10 112 +#define K01 4322 +#define K11 135 + +#define N 16 + +/* SLP with load permutation and loop-based vectorization. */ +void foo (int *__restrict__ pInput, int *__restrict__ pOutput, + int *__restrict__ pInput2, int *__restrict__ pOutput2) +{ + int i, a, b, c, d; + + for (i = 0; i < N / 3; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + d = *pInput2++; + + *pOutput++ = M00 * a + M01 * b + M02 * c; + *pOutput++ = M10 * a + M11 * b + M12 * c; + *pOutput++ = M20 * a + M21 * b + M22 * c; + + /* Loop-based vectorization. */ + *pOutput2++ = K00 * d; + } +} + +int main (int argc, const char* argv[]) +{ + int input[N], output[N], i; + int check_results[N] = {1470, 395, 28271, 5958, 1655, 111653, 10446, 2915, 195035, 14934, 4175, 278417, 19422, 5435, 361799, 0}; + int input2[N], output2[N]; + int check_results2[N] = {0, 405, 810, 1215, 1620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i%256; + input2[i] = i%256; + output[i] = 0; + output2[i] = 0; + if (input[i] > 200) + abort (); + } + + foo (input, output, input2, output2); + + for (i = 0; i < N; i++) + if (output[i] != check_results[i] || output2[i] != check_results2[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-8.c b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c new file mode 100644 index 000000000..d211ef943 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 200 + +void foo (unsigned char *__restrict__ pInput, unsigned char *__restrict__ pOutput) +{ + unsigned char i, a, b, c; + + for (i = 0; i < N / 3; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + + *pOutput++ = a + b + c + 3; + *pOutput++ = a + b + c + 12; + *pOutput++ = a + b + c + 1; + } +} + +int main (int argc, const char* argv[]) +{ + unsigned char input[N], output[N], i; + unsigned char check_results[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i; + output[i] = 0; + if (input[i] > 256) + abort (); + } + + for (i = 0; i < N / 3; i++) + { + check_results[3*i] = 9 * i + 6; + check_results[3*i+1] = 9 * i + 15; + check_results[3*i+2] = 9 * i + 4; + } + + foo (input, output); + + for (i = 0; i < N - (N % 3); i++) + if (output[i] != check_results[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_perm_byte } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm_byte } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c new file mode 100644 index 000000000..d1653ba1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c @@ -0,0 +1,59 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 200 + +void foo (unsigned short *__restrict__ pInput, unsigned short *__restrict__ pOutput) +{ + unsigned short i, a, b, c; + + for (i = 0; i < N / 3; i++) + { + a = *pInput++; + b = *pInput++; + c = *pInput++; + + *pOutput++ = a + b + c + 3; + *pOutput++ = a + b + c + 12; + *pOutput++ = a + b + c + 1; + } +} + +int main (int argc, const char* argv[]) +{ + unsigned short input[N], output[N], i; + unsigned short check_results[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + input[i] = i; + output[i] = 0; + if (input[i] > 256) + abort (); + } + + for (i = 0; i < N / 3; i++) + { + check_results[3*i] = 9 * i + 6; + check_results[3*i+1] = 9 * i + 15; + check_results[3*i+2] = 9 * i + 4; + } + + foo (input, output); + + for (i = 0; i < N - (N % 3); i++) + if (output[i] != check_results[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 1 "vect" { target vect_perm_short } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c new file mode 100644 index 000000000..1667c5dc3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Vectorization of reduction using loop-aware SLP. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1, int res2, int res3) +{ + int i; + unsigned int udiff0 = 5, udiff1 = 10, udiff2 = 20, udiff3 = 30; + + for (i = 0; i < n; i++) { + udiff3 += (ub[4*i + 3] - uc[4*i + 3]); + udiff2 += (ub[4*i + 2] - uc[4*i + 2]); + udiff1 += (ub[4*i + 1] - uc[4*i + 1]); + udiff0 += (ub[4*i] - uc[4*i]); + } + + /* Check results: */ + if (udiff0 != res0 + || udiff1 != res1 + || udiff2 != res2 + || udiff3 != res3) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N/4, 53, 66, 84, 102); + main1 (N/4 - 1, 29, 40, 56, 72); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c new file mode 100644 index 000000000..92d666987 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Vectorization of reduction using loop-aware SLP (with unrolling). */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1, int res2, int res3) +{ + int i; + unsigned int udiff0 = 5, udiff1 = 10; + + for (i = 0; i < n; i++) { + udiff1 += (ub[2*i + 1] - uc[2*i + 1]); + udiff0 += (ub[2*i] - uc[2*i]); + } + + /* Check results: */ + if (udiff0 != res0 + || udiff1 != res1) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N/2, 117, 138, 84, 102); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c new file mode 100644 index 000000000..93ca0ff2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT1 21834 +#define DOT2 21876 + +unsigned short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* short->short->int dot product. + Not detected as a dot-product pattern. + Requires support for non-widneing multiplication and widening-summation. + Vectorized with loop-aware SLP. */ +__attribute__ ((noinline)) unsigned int +foo1(int len, int *result1, int *result2) +{ + int i; + unsigned int res1 = 10, res2 = 20; + unsigned short prod; + + for (i=0; i<len; i++) { + prod = X[2*i] * Y[2*i]; + res1 += prod; + prod = X[2*i+1] * Y[2*i+1]; + res2 += prod; + } + + *result1 = res1; + *result2 = res2; + + return 0; +} + +int main (void) +{ + unsigned int dot1, dot2; + unsigned short i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + } + + foo1 (N/2, &dot1, &dot2); + + if (dot1 != DOT1 || dot2 != DOT2) + abort (); + + return 0; +} + +/* The initialization loop in main also gets vectorized. */ +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target { vect_short_mult && { vect_widen_sum_hi_to_si && vect_unpack } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_widen_sum_hi_to_si_pattern || { ! vect_unpack } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c new file mode 100644 index 000000000..5df53f919 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +unsigned int uc[N]; + +/* Vectorization of reduction using loop-aware SLP. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1, int res2, int res3, int res4, int res5, int res6, int res7) +{ + int i; + unsigned int max0 = 5, max1 = 10, max2 = 20, max3 = 30, max4 = 2, max5 = 13, max6 = 7, max7 = 313; + + for (i = 0; i < n; i++) { + max2 = max2 < uc[8*i+2] ? uc[8*i+2] : max2; + max3 = max3 < uc[8*i+3] ? uc[8*i+3] : max3; + max1 = max1 < uc[8*i+1] ? uc[8*i+1] : max1; + max7 = max7 < uc[8*i+7] ? uc[8*i+7] : max7; + max6 = max6 < uc[8*i+6] ? uc[8*i+6] : max6; + max0 = max0 < uc[8*i] ? uc[8*i] : max0; + max4 = max4 < uc[8*i+4] ? uc[8*i+4] : max4; + max5 = max5 < uc[8*i+5] ? uc[8*i+5] : max5; + } + + /* Check results: */ + if (max0 != res0 + || max1 != res1 + || max2 != res2 + || max3 != res3 + || max4 != res4 + || max5 != res5 + || max6 != res6 + || max7 != res7) + abort (); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + { + uc[i] = i+3; + __asm__ volatile (""); + } + + main1 (N/8, 123, 124, 125, 126, 127, 128, 129, 313); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c new file mode 100644 index 000000000..40958f131 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int c[N]; + +/* Vectorization of reduction using loop-aware SLP. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1) +{ + int i; + int max0 = -100, max1 = -313; + + for (i = 0; i < n; i++) { + max1 = max1 < c[2*i+1] ? c[2*i+1] : max1; + max0 = max0 < c[2*i] ? c[2*i] : max0; + } + + /* Check results: */ + if (max0 != res0 + || max1 != res1) + abort (); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + c[i] = (i+3) * -1; + + c[0] = c[1] = -100; + main1 (N/2, -5, -6); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-6.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-6.c new file mode 100644 index 000000000..ccfb888fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-6.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int a[N], b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* Vectorization of reduction. Loop-aware SLP is not possible, because of + different arrays. */ + +__attribute__ ((noinline)) +int main1 (int n, int res0, int res1) +{ + int i; + int sum0 = 0, sum1 = 0; + + for (i = 0; i < n; i++) { + sum1 += a[2*i]; + sum0 += b[2*i]; + } + + /* Check results: */ + if (sum0 != res0 + || sum1 != res1) + abort (); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + a[i] = b[i] = i; + + main1 (N/2, 4032, 4032); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { vect_no_int_add || { ! vect_unpack } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "different interleaving chains in one node" 1 "vect" { target { ! vect_no_int_add } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-widen-mult-s16.c b/gcc/testsuite/gcc.dg/vect/slp-widen-mult-s16.c new file mode 100644 index 000000000..2eb73f380 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-widen-mult-s16.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; + +int result[N]; + +/* short->int widening-mult */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len/2; i++) { + result[2*i] = X[2*i] * Y[2*i]; + result[2*i+1] = X[2*i+1] * Y[2*i+1]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + foo1 (N); + + for (i=0; i<N; i++) { + if (result[i] != X[i] * Y[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_hi_to_si || vect_unpack } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_widen_mult_hi_to_si || vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/slp-widen-mult-u8.c b/gcc/testsuite/gcc.dg/vect/slp-widen-mult-u8.c new file mode 100644 index 000000000..fb3292ad4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/slp-widen-mult-u8.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; + +unsigned short result[N]; + +/* char->short widening-mult */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len/2; i++) { + result[2*i] = X[2*i] * Y[2*i]; + result[2*i+1] = X[2*i+1] * Y[2*i+1]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + foo1 (N); + + for (i=0; i<N; i++) { + if (result[i] != X[i] * Y[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_qi_to_hi || vect_unpack } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_widen_mult_hi_to_si || vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/trapv-vect-reduc-4.c b/gcc/testsuite/gcc.dg/vect/trapv-vect-reduc-4.c new file mode 100644 index 000000000..78ff73237 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/trapv-vect-reduc-4.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-do compile } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +int main1 (int x, int max_result) +{ + int i; + int b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + int c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + int diff = 2; + int max = x; + int min = 10; + + for (i = 0; i < N; i++) { + diff += (b[i] - c[i]); + } + + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != 0) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100); + main1 (0, 15); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/tree-vect.h b/gcc/testsuite/gcc.dg/vect/tree-vect.h new file mode 100644 index 000000000..ed59d7976 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/tree-vect.h @@ -0,0 +1,71 @@ +/* Check if system supports SIMD */ +#include <signal.h> + +#if defined(__i386__) || defined(__x86_64__) +# include "cpuid.h" +#endif + +extern void abort (void); +extern void exit (int); + +static void +sig_ill_handler (int sig) +{ + exit(0); +} + +static void __attribute__((noinline)) +check_vect (void) +{ + signal(SIGILL, sig_ill_handler); +#if defined(__PAIRED__) + /* 750CL paired-single instruction, 'ps_mul %v0,%v0,%v0'. */ + asm volatile (".long 0x10000032"); +#elif defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(powerpc) + /* Altivec instruction, 'vor %v0,%v0,%v0'. */ + asm volatile (".long 0x10000484"); +#elif defined(__i386__) || defined(__x86_64__) + { + int a, b, c, d, want_level, want_c, want_d; + + /* Determine what instruction set we've been compiled for, and detect + that we're running with it. This allows us to at least do a compile + check for, e.g. SSE4.1 when the machine only supports SSE2. */ +# ifdef __XOP__ + want_level = 0x80000001, want_c = bit_XOP, want_d = 0; +# elif defined(__AVX__) + want_level = 1, want_c = bit_AVX, want_d = 0; +# elif defined(__SSE4_1__) + want_level = 1, want_c = bit_SSE4_1, want_d = 0; +# elif defined(__SSSE3__) + want_level = 1, want_c = bit_SSSE3, want_d = 0; +# else + want_level = 1, want_c = 0, want_d = bit_SSE2; +# if defined(__sun__) && defined(__svr4__) + /* Before Solaris 9 4/04, trying to execute an SSE2 instruction gives + SIGILL even if the CPU can handle them. */ + asm volatile ("unpcklpd %xmm0,%xmm2"); +# endif +# endif + + if (!__get_cpuid (want_level, &a, &b, &c, &d) + || ((c & want_c) | (d & want_d)) == 0) + exit (0); + } +#elif defined(__sparc__) + asm volatile (".word\t0x81b007c0"); +#elif defined(__arm__) + { + /* On some processors without NEON support, this instruction may + be a no-op, on others it may trap, so check that it executes + correctly. */ + long long a = 0, b = 1; + asm ("vorr %P0, %P1, %P2" + : "=w" (a) + : "0" (a), "w" (b)); + if (a != 1) + exit (0); + } +#endif + signal (SIGILL, SIG_DFL); +} diff --git a/gcc/testsuite/gcc.dg/vect/unswitch-loops-pr26969.c b/gcc/testsuite/gcc.dg/vect/unswitch-loops-pr26969.c new file mode 100644 index 000000000..b92a7fb7c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/unswitch-loops-pr26969.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void +ruby_re_compile_fastmap (char *fastmap, int options) +{ + int j; + for (j = 0; j < (1 << 8); j++) + { + if (j != '\n' || (options & 4)) + fastmap[j] = 1; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vec-scal-opt.c b/gcc/testsuite/gcc.dg/vect/vec-scal-opt.c new file mode 100644 index 000000000..f5e54e71a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vec-scal-opt.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_shift } */ +/* { dg-require-effective-target vect_int } */ + +#define vidx(type, vec, idx) (*((type *) &(vec) + idx)) +#define vector(elcount, type) \ +__attribute__((vector_size((elcount)*sizeof(type)))) type + +short k; + +int main (int argc, char *argv[]) { + k = argc; + vector(8, short) v0 = {argc,1,2,3,4,5,6,7}; + vector(8, short) v2 = {k, k,k,k,k,k,k,k}; + vector(8, short) r1; + + r1 = v0 >> v2; + + return vidx(short, r1, 0); +} + +/* { dg-final { scan-tree-dump-times ">> k.\[0-9_\]*" 1 "veclower" { target vect_shift_scalar } } } */ +/* { dg-final { cleanup-tree-dump "veclower" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vec-scal-opt1.c b/gcc/testsuite/gcc.dg/vect/vec-scal-opt1.c new file mode 100644 index 000000000..0c00c718e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vec-scal-opt1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_shift } */ +/* { dg-require-effective-target vect_int } */ + +#define vidx(type, vec, idx) (*((type *) &(vec) + idx)) +#define vector(elcount, type) \ +__attribute__((vector_size((elcount)*sizeof(type)))) type + +short k; + +int main (int argc, char *argv[]) { + vector(8, short) v0 = {argc,1,2,3,4,5,6,7}; + vector(8, short) r1; + + r1 = v0 >> (vector(8, short)){2,2,2,2,2,2,2,2}; + + return vidx(short, r1, 0); +} + +/* { dg-final { scan-tree-dump-times ">> 2" 1 "veclower" { target vect_shift_scalar } } } */ +/* { dg-final { cleanup-tree-dump "veclower" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vec-scal-opt2.c b/gcc/testsuite/gcc.dg/vect/vec-scal-opt2.c new file mode 100644 index 000000000..5e79fb586 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vec-scal-opt2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_shift } */ +/* { dg-require-effective-target vect_int } */ + +#define vidx(type, vec, idx) (*((type *) &(vec) + idx)) +#define vector(elcount, type) \ +__attribute__((vector_size((elcount)*sizeof(type)))) type + +int main (int argc, char *argv[]) { + vector(8, short) v0 = {argc,1,2,3,4,5,6,7}; + vector(8, short) v1 = {2,2,2,2,2,2,2,2}; + vector(8, short) r1; + + r1 = v0 >> v1; + + return vidx(short, r1, 0); +} + +/* { dg-final { scan-tree-dump-times ">> 2" 1 "veclower" { target vect_shift_scalar } } } */ +/* { dg-final { cleanup-tree-dump "veclower" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-1.c b/gcc/testsuite/gcc.dg/vect/vect-1.c new file mode 100644 index 000000000..21975afa0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-1.c @@ -0,0 +1,90 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_float } */ + +#define N 16 + +void fbar (float *); +void ibar (int *); +void sbar (short *); + +/* multiple loops */ + +foo (int n) +{ + float a[N+1]; + float b[N]; + float c[N]; + float d[N]; + int ia[N]; + int ib[N]; + int ic[N]; + int i,j; + int diff = 0; + char cb[N]; + char cc[N]; + char image[N][N]; + char block[N][N]; + + /* Vectorizable. */ + diff = 0; + for (i = 0; i < N; i++) { + diff += (cb[i] - cc[i]); + } + ibar (&diff); + + + /* Vectorizable. */ + diff = 0; + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + diff += (image[i][j] - block[i][j]); + } + } + ibar (&diff); + + + /* Vectorizable. */ + for (i = 0; i < N; i++){ + a[i] = b[i]; + } + fbar (a); + + + /* Vectorizable. */ + for (i = 0; i < N; i++){ + a[i] = b[i] + c[i] + d[i]; + } + fbar (a); + + + /* Strided access. Vectorizable on platforms that support load of strided + accesses (extract of even/odd vector elements). */ + for (i = 0; i < N/2; i++){ + a[i] = b[2*i+1] * c[2*i+1] - b[2*i] * c[2*i]; + d[i] = b[2*i] * c[2*i+1] + b[2*i+1] * c[2*i]; + } + fbar (a); + + + /* Vectorizable. */ + for (i = 0; i < N; i++){ + a[i] = b[i] + c[i]; + d[i] = b[i] + c[i]; + ia[i] = ib[i] + ic[i]; + } + ibar (ia); + fbar (a); + fbar (d); + + /* Not vetorizable yet (too conservative dependence test). */ + for (i = 0; i < N; i++){ + a[i] = b[i] + c[i]; + a[i+1] = b[i] + c[i]; + } + fbar (a); +} + +/* { dg-final { scan-tree-dump-times "vectorized 6 loops" 1 "vect" { target vect_extract_even_odd_wide } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 5 loops" 1 "vect" { xfail vect_extract_even_odd_wide } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-10.c b/gcc/testsuite/gcc.dg/vect/vect-10.c new file mode 100644 index 000000000..6447b75a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-10.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#define N 16 + +short a[N]; +short d[N]; + +int foo () +{ + int i; + short b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + short c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + /* Strided access pattern. */ + for (i = 0; i < N/2; i++) + { + a[i] = b[2*i+1] * c[2*i+1] - b[2*i] * c[2*i]; + d[i] = b[2*i] * c[2*i+1] + b[2*i+1] * c[2*i]; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { ! vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-100.c b/gcc/testsuite/gcc.dg/vect/vect-100.c new file mode 100644 index 000000000..9388084dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-100.c @@ -0,0 +1,80 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 9 + +struct extraction +{ + int a[N]; + int b[N]; +}; + +static int a[N] = {1,2,3,4,5,6,7,8,9}; +static int b[N] = {2,3,4,5,6,7,8,9,0}; + +__attribute__ ((noinline)) +int main1 () { + int i; + struct extraction *p; + + p = (struct extraction *) malloc (sizeof (struct extraction)); + + /* Vectorizable: alias analysis determines that p can't point to a and/or b. */ + for (i = 0; i < N; i++) + { + p->a[i] = a[i]; + p->b[i] = b[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->a[i] != a[i] || p->b[i] != b[i]) + abort(); + } + + return 0; +} + +__attribute__ ((noinline)) +int main2 () { + int i; + int c[N] = {1,2,3,4,5,6,7,8,9}; + int d[N] = {2,3,4,5,6,7,8,9,0}; + struct extraction *p; + p = (struct extraction *) malloc (sizeof (struct extraction)); + + /* Vectorizable: c and d are local arrays. */ + for (i = 0; i < N; i++) + { + p->a[i] = c[i]; + p->b[i] = d[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->a[i] != c[i] || p->b[i] != d[i]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + main2 (); + + return 0; +} + +/* Requires versioning. */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-103.c b/gcc/testsuite/gcc.dg/vect/vect-103.c new file mode 100644 index 000000000..108f56d37 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-103.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 9 + +struct extraction +{ + int a[N]; + int b[N]; +}; + +static int a[N] = {1,2,3,4,5,6,7,8,9}; +static int b[N] = {17,24,7,0,2,3,4,31,82}; +static int c[N] = {9,17,24,7,0,2,3,4,31}; +volatile int foo; + +__attribute__ ((noinline)) +int main1 (int x, int y) { + int i; + struct extraction *p; + p = (struct extraction *) malloc (sizeof (struct extraction)); + + for (i = 0; i < N; i++) + { + p->a[i] = a[i]; + p->b[i] = b[i]; + if (foo == 135) + abort (); /* to avoid vectorization */ + } + + /* Vectorizable: distance > VF. */ + for (i = 0; i < N; i++) + { + *((int *)p + x + i) = *((int *)p + x + i + 8); + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->a[i] != c[i]) + abort(); + } + return 0; +} + +int main (void) +{ + check_vect (); + + foo = 0; + return main1 (0, N); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "dependence distance modulo vf == 0" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-104.c b/gcc/testsuite/gcc.dg/vect/vect-104.c new file mode 100644 index 000000000..5ea2f801a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-104.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 3 + +struct extraction +{ + int a[N][N]; + int b[N][N]; +}; + +static int a[N][N] = {{1,2,3},{4,5,6},{7,8,9}}; +static int b[N][N] = {{17,24,7},{0,2,3},{4,31,82}}; +static int c[N][N] = {{1,2,3},{4,5,5},{5,5,5}}; +volatile int foo; + +__attribute__ ((noinline)) +int main1 (int x) { + int i,j; + struct extraction *p; + p = (struct extraction *) malloc (sizeof (struct extraction)); + + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + p->a[i][j] = a[i][j]; + p->b[i][j] = b[i][j]; + if (foo == 135) + abort (); /* to avoid vectorization */ + } + } + + /* Not vectorizable: distance = 1. */ + for (i = 1; i < N; i++) + { + for (j = 0; j < N; j++) + { + *((int *)p + x + i + j + 1) = *((int *)p + x + i + j); + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (p->a[i][j] != c[i][j]) + abort(); + } + } + return 0; +} + +int main (void) +{ + check_vect (); + + foo = 0; + return main1 (N); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-105.c b/gcc/testsuite/gcc.dg/vect/vect-105.c new file mode 100644 index 000000000..bbf42af89 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-105.c @@ -0,0 +1,72 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 4 + +struct extraction +{ + int a[N][N]; + int b[N][N]; +}; + +static int a[N][N] = {{1,2,3,11},{4,5,6,12},{7,8,9,13},{34,45,67,83}}; +static int b[N][N] = {{17,28,15,23},{0,2,3,24},{4,31,82,25},{29,31,432,256}}; +static int c[N][N] = {{1,2,3,11},{4,9,13,34},{45,67,83,13},{34,45,67,83}}; + +volatile int y; + +__attribute__ ((noinline)) +int main1 (int x) { + int i,j; + struct extraction *p; + p = (struct extraction *) malloc (sizeof (struct extraction)); + + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + p->a[i][j] = a[i][j]; + p->b[i][j] = b[i][j]; + /* Because Y is volatile, the compiler cannot move this check out + of the loop. */ + if (y) + abort (); /* to avoid vectorization */ + } + } + + /* Vectorizable: distance > number of iterations. */ + for (i = 1; i < N; i++) + { + for (j = 0; j < N; j++) + { + *((int *)p + x + i + j) = *((int *)p + x + i + j + 5); + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (p->a[i][j] != c[i][j]) + abort(); + } + } + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (N); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-106.c b/gcc/testsuite/gcc.dg/vect/vect-106.c new file mode 100644 index 000000000..d578d8143 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-106.c @@ -0,0 +1,73 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 9 + +static int a[N] = {1,2,3,4,5,6,7,8,9}; +static int b[N] = {2,3,4,5,6,7,8,9,0}; + +__attribute__ ((noinline)) +int main1 () { + int i; + int *p, *q, *p1, *q1; + p = (unsigned int *) malloc (sizeof (unsigned int) * N); + q = (unsigned int *) malloc (sizeof (unsigned int) * N); + + p1 = p; q1 = q; + + /* Vectorizable, before pointer plus we would get a redundant cast + (caused by pointer arithmetics), alias analysis fails to distinguish + between the pointers. */ + for (i = 0; i < N; i++) + { + *(q + i) = a[i]; + *(p + i) = b[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (*q != a[i] || *p != b[i]) + abort(); + q++; + p++; + } + + q = q1; + p = p1; + /* Vectorizable. */ + for (i = 0; i < N; i++) + { + *q = b[i]; + *p = a[i]; + q++; + p++; + } + + q = q1; + p = p1; + /* check results: */ + for (i = 0; i < N; i++) + { + if (*q != b[i] || *p != a[i]) + abort(); + q++; + p++; + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-107.c b/gcc/testsuite/gcc.dg/vect/vect-107.c new file mode 100644 index 000000000..201d4ab4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-107.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + float a[N]; + + /* Strided access. Vectorizable on platforms that support load of strided + accesses (extract of even/odd vector elements). */ + for (i = 0; i < N/2; i++) + { + a[i] = b[2*i+1] * c[2*i+1] - b[2*i] * c[2*i]; + d[i] = b[2*i] * c[2*i+1] + b[2*i+1] * c[2*i]; + } + + /* Check results. */ + for (i = 0; i < N/2; i++) + { + if (a[i] != b[2*i+1] * c[2*i+1] - b[2*i] * c[2*i] + || d[i] != b[2*i] * c[2*i+1] + b[2*i+1] * c[2*i]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_extract_even_odd_wide } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { xfail vect_extract_even_odd_wide } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-108.c b/gcc/testsuite/gcc.dg/vect/vect-108.c new file mode 100644 index 000000000..28e85b2e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-108.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ia[N]; + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + + /* This loop is vectorized on platforms that support vect_int_mult. */ + for (i = 0; i < N; i++) + { + ia[i] = ib[i] * ic[i]; + } + + /* Check results. */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i] * ic[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-109.c b/gcc/testsuite/gcc.dg/vect/vect-109.c new file mode 100644 index 000000000..1f2f53ed9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-109.c @@ -0,0 +1,80 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +short sa[N]; +short sc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +short sb[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +int ia[N]; +int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) +int main1 (int n) +{ + int i; + + /* Multiple types with different sizes, used in idependent + copmutations. Vectorizable. */ + for (i = 0; i < n; i++) + { + sa[i+2] = sb[i] + sc[i]; + ia[i+1] = ib[i] + ic[i]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (sa[i+2] != sb[i] + sc[i] || ia[i+1] != ib[i] + ic[i]) + abort (); + } + + return 0; +} + +int main2 (int n) +{ + int i; + + /* Multiple types with different sizes, used in idependent + copmutations. Vectorizable. */ + for (i = 0; i < n; i++) + { + ia[i+1] = ib[i] + ic[i]; + sa[i] = sb[i] + sc[i]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (sa[i] != sb[i] + sc[i] || ia[i+1] != ib[i] + ic[i]) + abort (); + } + + return 0; +} + + +int main (void) +{ + check_vect (); + + main1 (N-2); + main2 (N-1); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_element_align } } } */ +/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 2 "vect" { xfail vect_element_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_element_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-11.c b/gcc/testsuite/gcc.dg/vect/vect-11.c new file mode 100644 index 000000000..3df8f47b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-11.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int ia[N]; +int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + /* Not vectorizable yet (integer mult). */ + for (i = 0; i < N; i++) + { + ia[i] = ib[i] * ic[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i] * ic[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-110.c b/gcc/testsuite/gcc.dg/vect/vect-110.c new file mode 100644 index 000000000..b62ad94fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-110.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +static __attribute__ ((noinline)) int +main1 (void) +{ + int i; + float a[N]; + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + + /* Too conservative dependence test. */ + for (i = 0; i < N - 1; i++){ + a[i] = b[i] + c[i]; + a[i+1] = b[i] + c[i]; + } + + /* Check results. */ + for (i = 0; i < N - 1; i++){ + if (a[i] != b[i] + c[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-112.c b/gcc/testsuite/gcc.dg/vect/vect-112.c new file mode 100644 index 000000000..4d954d108 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-112.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +char cb[N] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}; +char cc[N] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + int diff = 0; + + /* Cross-iteration cycle. */ + diff = 0; + for (i = 0; i < N; i++) { + diff += (cb[i] - cc[i]); + } + + /* Check results. */ + if (diff != 16) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-113.c b/gcc/testsuite/gcc.dg/vect/vect-113.c new file mode 100644 index 000000000..0d36c16c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-113.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + float a[N]; + + /* Induction and type conversion. */ + for ( i = 0; i < N; i++) + { + a[i] = i; + } + + for ( i = 0; i < N; i++) + { + if (a[i] != i) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target powerpc*-*-* i?86-*-* x86_64-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-114.c b/gcc/testsuite/gcc.dg/vect/vect-114.c new file mode 100644 index 000000000..4bc786278 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-114.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + float a[N]; + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + + /* Reverse access and forward access. */ + for (i = N; i > 0; i--) + { + a[N-i] = b[i-1]; + } + + /* Check results. */ + for (i = 0; i <N; i++) + { + if (a[i] != b[N-1-i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { target { ! { vect_perm && vect_hw_misalign } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm && vect_hw_misalign } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-115.c b/gcc/testsuite/gcc.dg/vect/vect-115.c new file mode 100644 index 000000000..ce6eaf454 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-115.c @@ -0,0 +1,77 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct s{ + int b[N]; + int c[N]; + int m; +}; + +struct t{ + struct s strc_s; + int m; +}; + +struct test1{ + struct t strc_t; + struct t *ptr_t; + int k; + int l; +}; + +int a[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + struct test1 tmp1; + struct t tmp2; + + tmp1.ptr_t = &tmp2; + + /* DR bases comparison: record and array. */ + for (i = 0; i < N; i++) + { + tmp1.strc_t.strc_s.b[i] = a[i]; + } + + /* Check results. */ + for (i = 0; i < N; i++) + { + if (tmp1.strc_t.strc_s.b[i] != a[i]) + abort(); + } + + /* DR bases comparison: record containing ptr and array. */ + for (i = 0; i < N; i++) + { + tmp1.ptr_t->strc_s.c[i] = a[i]; + } + + /* Check results. */ + for (i = 0; i < N; i++) + { + if (tmp1.ptr_t->strc_s.c[i] != a[i]) + abort(); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-116.c b/gcc/testsuite/gcc.dg/vect/vect-116.c new file mode 100644 index 000000000..f59e8abf9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-116.c @@ -0,0 +1,33 @@ +/* { dg-require-effective-target vect_int } */ +/* Assuming we can vectorize char multiplication, here's an execute test. */ + +#include <stdarg.h> +#include "tree-vect.h" + +extern void abort (void); + +__attribute__ ((noinline)) +void foo() +{ + static unsigned char A[256], B[256], C[256]; + int i; + + for (i = 0; i < 256; ++i) + A[i] = B[i] = i; + + for (i = 0; i < 256; ++i) + C[i] = A[i] * B[i]; + + for (i = 0; i < 256; ++i) + if (C[i] != (unsigned char)(i * i)) + abort (); +} + +int main() +{ + check_vect (); + foo(); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-117.c b/gcc/testsuite/gcc.dg/vect/vect-117.c new file mode 100644 index 000000000..920e29314 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-117.c @@ -0,0 +1,66 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +#define N 5 + +static int a[N][N] = {{ 1, 2, 3, 4, 5}, + { 6, 7, 8, 9,10}, + {11,12,13,14,15}, + {16,17,18,19,20}, + {21,22,23,24,25}}; + +static int c[N][N] = {{ 1, 2, 3, 4, 5}, + { 7, 9,11, 13,15}, + {18,21,24,27,30}, + {34,38,42,46,50}, + {55,60,65,70,75}}; + +volatile int foo; + +__attribute__ ((noinline)) +int main1 (int A[N][N], int n) +{ + + int i,j; + + /* vectorizable */ + for (i = 1; i < N; i++) + { + for (j = 0; j < n; j++) + { + A[i][j] = A[i-1][j] + A[i][j]; + } + } + + return 0; +} + +int main (void) +{ + int i,j; + + check_vect (); + + foo = 0; + main1 (a, N); + + /* check results: */ + + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (a[i][j] != c[i][j]) + abort(); + } + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "possible dependence between data-refs" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-118.c b/gcc/testsuite/gcc.dg/vect/vect-118.c new file mode 100644 index 000000000..bc08e9108 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-118.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void f(short * __restrict__ a, short * __restrict__ b, short * __restrict__ x) +{ + int i; + for (i=0;i<1024;i++) + x[i] = a[i] + b[i]; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-11a.c b/gcc/testsuite/gcc.dg/vect/vect-11a.c new file mode 100644 index 000000000..2da903b1b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-11a.c @@ -0,0 +1,65 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +extern void abort (void); + +unsigned int A[8] = {0x08000000,0xffffffff,0xff0000ff,0xf0000001, + 0x08000000,0xffffffff,0xff0000ff,0xf0000001}; +unsigned int B[8] = {0x08000000,0x08000001,0xff0000ff,0xf0000001, + 0x08000000,0x08000001,0xff0000ff,0xf0000001}; +unsigned int Answer[8] = {0,0xf7ffffff,0x0200fe01,0xe0000001, + 0,0xf7ffffff,0x0200fe01,0xe0000001}; +unsigned int C[8]; + +__attribute__ ((noinline)) +void u () +{ + int i, j; + + for (i=0; i<8; i++) + C[i] = A[i] * B[i]; + for (i=0; i<8; i++) + if (C[i] != Answer[i]) + abort (); +} + +signed int D[8] = {0x08000000,0xffffffff,0xff0000ff,0xf0000001, + 0x08000000,0xffffffff,0xff0000ff,0xf0000001}; +signed int E[8] = {0x08000000,0x08000001,0xff0000ff,0xf0000001, + 0x08000000,0x08000001,0xff0000ff,0xf0000001}; +signed int Dnswer[8] = {0,0xf7ffffff,0x0200fe01, 0xe0000001, + 0,0xf7ffffff,0x0200fe01, 0xe0000001}; +signed int F[8]; + +__attribute__ ((noinline)) +void s() +{ + int i, j; + + for (i=0; i<8; i++) + F[i] = D[i] * E[i]; + for (i=0; i<8; i++) + if (F[i] != Dnswer[i]) + abort (); +} + +__attribute__ ((noinline)) +int main1 () +{ + u(); + s(); + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-12.c b/gcc/testsuite/gcc.dg/vect/vect-12.c new file mode 100644 index 000000000..80a08c802 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-12.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int i; + int ia[N]; + int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + short sa[N]; + short sc[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + + /* Multiple types with different nunits in vector. */ + for (i = 0; i < N; i++) + { + ia[i] = ib[i] + ic[i]; + sa[i] = sb[i] + sc[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i] + ic[i] || sa[i] != sb[i] + sc[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-13.c b/gcc/testsuite/gcc.dg/vect/vect-13.c new file mode 100644 index 000000000..ba8665bdc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-13.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int a[N]; +int results[N] = {0,1,2,3,0,0,0,0,0,0,0,0,12,13,14,15}; +int b[N] = {0,1,2,3,-4,-5,-6,-7,-8,-9,-10,-11,12,13,14,15}; + +__attribute__ ((noinline)) +int main1() +{ + int i; + + /* Max pattern. */ + for (i = 0; i < N; i++) + { + a[i] = (b[i] >= 0 ? b[i] : 0); + } + + /* Check results */ + for (i = 0; i < N; i++) + { + if (a[i] != results[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-14.c b/gcc/testsuite/gcc.dg/vect/vect-14.c new file mode 100644 index 000000000..35e48cc36 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-14.c @@ -0,0 +1,37 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int i; + int ia[N]; + + /* Induction. */ + for ( i = 0; i < N; i++) { + ia[i] = i; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != i) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect(); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-15.c b/gcc/testsuite/gcc.dg/vect/vect-15.c new file mode 100644 index 000000000..ba7599162 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-15.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int i; + int a[N]; + int b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + + /* Not vectorizable yet (reverse access and forward access). */ + for (i = N; i > 0; i--) + { + a[N-i] = b[i-1]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (a[i] != b[N-1-i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect(); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm && vect_hw_misalign } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-16.c b/gcc/testsuite/gcc.dg/vect/vect-16.c new file mode 100644 index 000000000..698370529 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-16.c @@ -0,0 +1,38 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 240 + +__attribute__ ((noinline)) +int main1 () +{ + int i; + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + float diff; + + diff = 0; + for (i = 0; i < N; i++) { + diff += (b[i] - c[i]); + } + + /* check results: */ + if (diff != DIFF) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* Requires fast-math. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-17.c b/gcc/testsuite/gcc.dg/vect/vect-17.c new file mode 100644 index 000000000..7c675fced --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-17.c @@ -0,0 +1,129 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + int ic[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char ca[N]; + char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char cc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = ib[i] & ic[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != (ib[i] & ic[i])) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = cb[i] & cc[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ca[i] != (cb[i] & cc[i])) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = sb[i] & sc[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != (sb[i] & sc[i])) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_bitwise } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-18.c b/gcc/testsuite/gcc.dg/vect/vect-18.c new file mode 100644 index 000000000..8a2baab3a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-18.c @@ -0,0 +1,128 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + int ic[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char ca[N]; + char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char cc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = (ib[i] | ic[i]); + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != (ib[i] | ic[i])) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = (cb[i] | cc[i]); + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != (cb[i] | cc[i])) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = (sb[i] | sc[i]); + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != (sb[i] | sc[i])) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_bitwise } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-19.c b/gcc/testsuite/gcc.dg/vect/vect-19.c new file mode 100644 index 000000000..df2166a58 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-19.c @@ -0,0 +1,128 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + int ic[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char ca[N]; + char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char cc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = ib[i] ^ ic[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != (ib[i] ^ ic[i])) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = cb[i] ^ cc[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ca[i] != (cb[i] ^ cc[i])) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = sb[i] ^ sc[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != (sb[i] ^ sc[i])) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_bitwise } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-2.c b/gcc/testsuite/gcc.dg/vect/vect-2.c new file mode 100644 index 000000000..5d4fc914a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-2.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +char ca[N]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + ca[i] = cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != cb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-20.c b/gcc/testsuite/gcc.dg/vect/vect-20.c new file mode 100644 index 000000000..deed2da44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-20.c @@ -0,0 +1,100 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + signed char ca[N]; + signed char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = ~ib[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != ~ib[i]) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = ~cb[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ca[i] != ~cb[i]) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = ~sb[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != ~sb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_bitwise } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-21.c b/gcc/testsuite/gcc.dg/vect/vect-21.c new file mode 100644 index 000000000..7a57506a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-21.c @@ -0,0 +1,129 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + int ic[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char ca[N]; + char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char cc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = !ib[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != !ib[i]) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = !cb[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ca[i] != !cb[i]) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = !sb[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != !sb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-22.c b/gcc/testsuite/gcc.dg/vect/vect-22.c new file mode 100644 index 000000000..369fab112 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-22.c @@ -0,0 +1,126 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + signed char ca[N]; + signed char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + float fa[N]; + float fb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = -ib[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != -ib[i]) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = -cb[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ca[i] != -cb[i]) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = -sb[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != -sb[i]) + abort (); + } + + /* Check floats. */ + + for (i = 0; i < N; i++) + { + fa[i] = -fb[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (fa[i] != -fb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-23.c b/gcc/testsuite/gcc.dg/vect/vect-23.c new file mode 100644 index 000000000..7991bb2d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-23.c @@ -0,0 +1,128 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +__attribute__ ((noinline)) int +main1 () +{ + int i; + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + int ic[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char ca[N]; + char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char cc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = ib[i] && ic[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != ib[i] && ic[i]) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = cb[i] && cc[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ca[i] != cb[i] && cc[i]) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = sb[i] && sc[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != sb[i] && sc[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-24.c b/gcc/testsuite/gcc.dg/vect/vect-24.c new file mode 100644 index 000000000..c1ae6b702 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-24.c @@ -0,0 +1,128 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +__attribute__ ((noinline)) int +main1 () +{ + int i; + int ia[N]; + int ib[N]= + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + int ic[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char ca[N]; + char cb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + char cc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sa[N]; + short sb[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + short sc[N] = + {1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0, + 1,1,0,0,1,0,1,0}; + + /* Check ints. */ + + for (i = 0; i < N; i++) + { + ia[i] = (ib[i] || ic[i]); + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ia[i] != (ib[i] || ic[i])) + abort (); + } + + /* Check chars. */ + + for (i = 0; i < N; i++) + { + ca[i] = (cb[i] || cc[i]); + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (ca[i] != (cb[i] || cc[i])) + abort (); + } + + /* Check shorts. */ + + for (i = 0; i < N; i++) + { + sa[i] = (sb[i] || sc[i]); + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (sa[i] != (sb[i] || sc[i])) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-25.c b/gcc/testsuite/gcc.dg/vect/vect-25.c new file mode 100644 index 000000000..769df4f4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-25.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +__attribute__ ((noinline)) +int main1 (int n, int *p) +{ + int i; + int ib[N]; + int ia[N]; + int k; + + for (i = 0; i < N; i++) + { + ia[i] = n; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != n) + abort (); + } + + k = *p; + for (i = 0; i < N; i++) + { + ib[i] = k; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ib[i] != k) + abort (); + } + + return 0; +} + +int main (void) +{ + int m = 8; + + check_vect (); + + return main1 (m, &m); +} + +/* { 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-26.c b/gcc/testsuite/gcc.dg/vect/vect-26.c new file mode 100644 index 000000000..bec111b69 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-26.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +/* unaligned store. */ + +__attribute__ ((noinline)) +int main1 () +{ + int i; + int ia[N+1]; + + for (i = 1; i <= N; i++) + { + ia[i] = 5; + } + + /* check results: */ + for (i = 1; i <= N; i++) + { + if (ia[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-27.c b/gcc/testsuite/gcc.dg/vect/vect-27.c new file mode 100644 index 000000000..4a2da227e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-27.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +/* unaligned load. */ + +int ia[N]; +int ib[N+1]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i=0; i <= N; i++) + { + ib[i] = i; + } + + for (i = 1; i <= N; i++) + { + ia[i-1] = ib[i]; + } + + /* check results: */ + for (i = 1; i <= N; i++) + { + if (ia[i-1] != ib[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* The initialization induction loop (with aligned access) is also vectorized. */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-28.c b/gcc/testsuite/gcc.dg/vect/vect-28.c new file mode 100644 index 000000000..794a7c8f4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-28.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 +#define OFF 3 + +/* unaligned store. */ + +__attribute__ ((noinline)) +int main1 (int off) +{ + int i; + int ia[N+OFF]; + + for (i = 0; i < N; i++) + { + ia[i+off] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i+off] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (0); /* aligned */ + main1 (OFF); /* unaligned */ + return 0; +} + +/* { 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} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-29.c b/gcc/testsuite/gcc.dg/vect/vect-29.c new file mode 100644 index 000000000..0ad284880 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-29.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 +#define OFF 3 + +/* unaligned load. */ + +int ia[N]; +int ib[N+OFF]; + +__attribute__ ((noinline)) +int main1 (int off) +{ + int i; + + for (i = 0; i < N+OFF; i++) + { + ib[i] = i; + } + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+off]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+off]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (0); /* aligned */ + main1 (OFF); /* unaligned */ + return 0; +} + +/* For targets that don't support misaligned loads we version for the load. + (The store is aligned). */ + +/* The initialization induction loop (with aligned access) is also vectorized. */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" {target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-3.c b/gcc/testsuite/gcc.dg/vect/vect-3.c new file mode 100644 index 000000000..d494deb85 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-3.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 20 + +float a[N]; +float e[N]; +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; +int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ia[N]; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + a[i] = b[i] + c[i] + d[i]; + e[i] = b[i] + c[i] + d[i]; + ia[i] = ib[i] + ic[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + float fres = b[i] + c[i] + d[i]; + int ires = ib[i] + ic[i]; + if (a[i] != fres || e[i] != fres || ia[i] != ires) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-30.c b/gcc/testsuite/gcc.dg/vect/vect-30.c new file mode 100644 index 000000000..408cbca4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-30.c @@ -0,0 +1,65 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float b[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; +float a[N]; +float c[N]; + +__attribute__ ((noinline)) +int main1 (int n) +{ + int i=0; + + /* Vectorized: unknown loop bound. */ + while (n--) { + a[i] = b[i]; + i++; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (a[i] != b[i]) + abort (); + } + + return 0; +} + +__attribute__ ((noinline)) +int main2 (unsigned int n) +{ + int i=0; + int nn = n; + + /* Vectorized: unknown loop bound. */ + while (n--) { + c[i] = b[i]; + i++; + } + + /* check results: */ + for (i = 0; i < nn; i++) + { + if (c[i] != b[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N); + main2 (N); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-31.c b/gcc/testsuite/gcc.dg/vect/vect-31.c new file mode 100644 index 000000000..8719fc9d2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-31.c @@ -0,0 +1,90 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +struct t{ + int k[N]; + int l; +}; + +struct s{ + char a; /* aligned */ + char b[N-1]; /* unaligned (offset 1B) */ + char c[N]; /* aligned (offset NB) */ + struct t d; /* aligned (offset 2NB) */ + struct t e; /* unaligned (offset 2N+4N+4 B) */ +}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + struct s tmp; + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.b[i] = 5; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.b[i] != 5) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.c[i] = 6; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.c[i] != 6) + abort (); + } + + /* aligned */ + for (i = 0; i < N/2; i++) + { + tmp.d.k[i] = 7; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.d.k[i] != 7) + abort (); + } + + /* unaligned */ + for (i = 0; i < N/2; i++) + { + tmp.e.k[i] = 8; + } + + /* check results: */ + for (i = 0; i <N/2; i++) + { + if (tmp.e.k[i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-32.c b/gcc/testsuite/gcc.dg/vect/vect-32.c new file mode 100644 index 000000000..c869f5ec9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-32.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + struct { + char ca[N]; + } s; + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-33.c b/gcc/testsuite/gcc.dg/vect/vect-33.c new file mode 100644 index 000000000..d35bce4d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-33.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +struct test { + char ca[N]; +}; + +extern struct test s; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != 5) + abort (); + } + + return 0; +} + +int main (void) +{ + 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} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-34.c b/gcc/testsuite/gcc.dg/vect/vect-34.c new file mode 100644 index 000000000..df18f774e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-34.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct { + char ca[N]; +} s; +char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + s.ca[i] = cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != cb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-35.c b/gcc/testsuite/gcc.dg/vect/vect-35.c new file mode 100644 index 000000000..0f4284a62 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-35.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + union { + unsigned char a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + unsigned char b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + } s; + int i; + + /* Initialization. */ + for (i = 0; i < N; i++) + { + s.b[i] = i; + } + + /* Dependence analysis fails cause s.a and s.b may overlap. + Use runtime aliasing test with versioning. */ + for (i = 0; i < N; i++) + { + s.a[i] = s.b[i] + 1; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.a[i] != i + 1) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "can't determine dependence between" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-36.c b/gcc/testsuite/gcc.dg/vect/vect-36.c new file mode 100644 index 000000000..20df3940a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-36.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int i; + struct { + char ca[N]; + char cb[N]; + } s; + + + for (i = 0; i < N; i++) + { + s.cb[i] = 3*i; + __asm__ volatile (""); + } + + for (i = 0; i < N; i++) + { + s.ca[i] = s.cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.ca[i] != s.cb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-38.c b/gcc/testsuite/gcc.dg/vect/vect-38.c new file mode 100644 index 000000000..8df8b5c9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-38.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +double cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +double ca[N]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + ca[i] = cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != cb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-4.c b/gcc/testsuite/gcc.dg/vect/vect-4.c new file mode 100644 index 000000000..d86fea11e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-4.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 20 + +float a[N]; +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; +float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + a[i] = b[i] * c[i]; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (a[i] != b[i] * c[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-40.c b/gcc/testsuite/gcc.dg/vect/vect-40.c new file mode 100644 index 000000000..d2c17d1d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-40.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +/* Aligned pointer accesses. + The loop bound is known and divisible by the vectorization factor. + No aliasing problems. + vect-46.c is similar to this one with one difference: + the loop bound is unknown. */ + +float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) + = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; +float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) + = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float *pa = a; + float *pb = b; + float *pc = c; + + for (i = 0; i < N; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + check_vect (); + main1 (); + return 0; +} + +/* { 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-42.c b/gcc/testsuite/gcc.dg/vect/vect-42.c new file mode 100644 index 000000000..b9faea491 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-42.c @@ -0,0 +1,71 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +/* Unaligned write access, aligned read accesses. + Since we are handling an unaligned store by peeling the loop, + the loads will become unaligned. + The loop bound is known and divisible by the vectorization factor. + No aliasing problems. */ + +__attribute__ ((noinline)) int +main1 (float * __restrict__ pa, float *pb, float *pc) +{ + float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + int i; + + /* We also vectorize this loop. */ + for (i = 0; i < N; i++) + { + b[i] = pb[i]; + c[i] = pc[i]; + } + + for (i = 0; i < N; i++) + { + pa[i] = b[i] * c[i]; + } + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (a,b,c); + bar (a,b,c); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { { ! vector_alignment_reachable } && { ! vect_element_align } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail { vect_no_align || { { ! vector_alignment_reachable } || vect_element_align } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_element_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || { { ! vector_alignment_reachable } || vect_element_align } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-44.c b/gcc/testsuite/gcc.dg/vect/vect-44.c new file mode 100644 index 000000000..ef1a4635b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-44.c @@ -0,0 +1,72 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +/* Unaligned pointer accesses, with unknown alignment. + The loop bound is known and divisible by the vectorization factor. + No aliasing problems. + vect-50.c is similar to this one with one difference: + the loop bound is unknown. + vect-45.c is similar to this one with one difference: + can't prove that pointers don't alias. */ + +__attribute__ ((noinline)) int +main1 (float * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc) +{ + int i; + + for (i = 0; i < N; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + float a[N+4] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N+4] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69}; + float c[N+4] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; + + check_vect (); + + main1 (a,b,c); + main1 (&a[1],b,c); + main1 (a,&b[1],c); + main1 (&a[1],&b[1],&c[1]); + + return 0; +} + +/* For targets that don't support misaligned loads we version for the + all three accesses (peeling to align the store will not force the + two loads to be aligned). */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {{! vect_no_align} && {! vect_hw_misalign} } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-46.c b/gcc/testsuite/gcc.dg/vect/vect-46.c new file mode 100644 index 000000000..d506d4329 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-46.c @@ -0,0 +1,64 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort(); + } + + return; +} + +/* Aligned pointer accesses. + The loop bound is unknown. + No aliasing problems. + vect-40.c is similar to this one with one difference: + the loop bound is known. */ + +float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) + = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; +float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) + = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +__attribute__ ((noinline)) int +main1 (int n) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float *pa = a; + float *pb = b; + float *pc = c; + + for (i = 0; i < n; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + int n=N; + check_vect (); + main1 (n); + return 0; +} + +/* { 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-48.c b/gcc/testsuite/gcc.dg/vect/vect-48.c new file mode 100644 index 000000000..e47ee00de --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-48.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +/* Unaligned pointer read accesses, aligned write access. + The loop bound is known and divisible by the vectorization factor. + No aliasing problems. + vect-56.c is similar to this one with one difference: + the alignment of the read accesses is known. + vect-52.c is similar to this one with one difference: + the loop bound is unknown. + vect-49.c is similar to this one with one difference: + aliasing is a problem. */ + +__attribute__ ((noinline)) int +main1 (float *pb, float *pc) +{ + float pa[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + int i; + + for (i = 0; i < N; i++) + { + pa[i] = pb[i] * pc[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + float b[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60}; + float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (b,c); + main1 (&b[1],c); + + return 0; +} + +/* For targets that don't support misaligned loads we version for the two loads. + (The store is aligned). */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-5.c b/gcc/testsuite/gcc.dg/vect/vect-5.c new file mode 100644 index 000000000..b5938ceae --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-5.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float a[N]; +float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + + i = 0; + j = 0; + while (i < 5*N) + { + a[j] = c[j]; + i += 5; + j++; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (a[i] != c[i]) + abort (); + } + + + for (i = N; i > 0; i--) + { + a[N-i] = d[N-i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (a[i] != d[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-50.c b/gcc/testsuite/gcc.dg/vect/vect-50.c new file mode 100644 index 000000000..068c804a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-50.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return; +} + +__attribute__ ((noinline)) int +main1 (int n, float * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc) +{ + int i; + + for (i = 0; i < n; i++) + { + pa[i] = pb[i] * pc[i]; + } + + bar (pa,pb,pc); + + return 0; +} + +/* Unaligned pointer accesses, with unknown alignment. + The loop bound is unknown. + No aliasing problems. + vect-44.c is similar to this one with one difference: + the loop bound is known. + vect-51.c is similar to this one with one difference: + can't prove that pointers don't alias. */ + +int main (void) +{ + int i; + float a[N]; + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (N,a,b,c); + return 0; +} + +/* For targets that don't support misaligned loads and don't support + misaligned stores we version for the all three accesses (peeling to + align the store will not force the two loads to be aligned). */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target vect_hw_misalign } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && { {! vect_no_align } && {! vect_hw_misalign } } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-52.c b/gcc/testsuite/gcc.dg/vect/vect-52.c new file mode 100644 index 000000000..af485abbd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-52.c @@ -0,0 +1,61 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +/* Unaligned pointer read accesses, aligned write access. + The loop bound is unknown. + No aliasing problems. + vect-60.c is similar to this one with one difference: + the alignment of the read accesses is known. + vect-48.c is similar to this one with one difference: + the loop bound is known. + vect-53.c is similar to this one with one difference: + aliasing is a problem. */ + +__attribute__ ((noinline)) int +main1 (int n, float *pb, float *pc) +{ + float pa[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + int i; + + for (i = 0; i < n; i++) + { + pa[i] = pb[i] * pc[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60}; + float c[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; + + check_vect (); + + main1 (N,&b[1],c); + main1 (N,&b[1],&c[1]); + + return 0; +} + +/* For targets that don't support misaligned loads we version for the two loads. + (The store is aligned). */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-54.c b/gcc/testsuite/gcc.dg/vect/vect-54.c new file mode 100644 index 000000000..629e82df5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-54.c @@ -0,0 +1,64 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i+1] != (pb[i+1] * pc[i+1])) + abort (); + } + + return; +} + +/* Unaligned pointer accesses, with a known alignment. + The loop bound is known and divisible by the vectorization factor. + No aliasing problems. + vect-58.c is similar to this one with one difference: + the loop bound is unknown. */ + +float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; +float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float *pa = a; + float *pb = b; + float *pc = c; + + for (i = 0; i < N/2; i++) + { + pa[i+1] = pb[i+1] * pc[i+1]; + } + + bar (a,b,c); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + main1 (); + + return 0; +} + +/* { 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" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-56.c b/gcc/testsuite/gcc.dg/vect/vect-56.c new file mode 100644 index 000000000..5a8130b11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-56.c @@ -0,0 +1,75 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i] != (pb[i+1] * pc[i+1])) + abort (); + } + + return; +} + +/* Unaligned pointer read accesses, aligned write access. + The loop bound is known and divisible by the vectorization factor. + No aliasing problems. + vect-48.c is similar to this one with one difference: + the alignment of the read accesses is unknown. + vect-60.c is similar to this one with one difference: + the loop bound is unknown. + vect-57.c is similar to this one with two differences: + aliasing is a problem, and the write access has unknown alignment. */ + +float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; +float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float *pa = a; + float *pb = b; + float *pc = c; + + for (i = 0; i < N/2; i++) + { + pa[i] = pb[i+1] * pc[i+1]; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i] != (pb[i+1] * pc[i+1])) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { xfail { vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { vect_element_align } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-58.c b/gcc/testsuite/gcc.dg/vect/vect-58.c new file mode 100644 index 000000000..fa8c91b30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-58.c @@ -0,0 +1,63 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i+1] != (pb[i+1] * pc[i+1])) + abort (); + } + + return; +} + +/* Unaligned pointer accesses, with a known alignment. + The loop bound is unknown. + No aliasing problems. + vect-54.c is similar to this one with one difference: + the loop bound is known. */ + +float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +__attribute__ ((noinline)) int +main1 (int n) +{ + int i; + float *pa = a; + float *pb = b; + float *pc = c; + + for (i = 0; i < n/2; i++) + { + pa[i+1] = pb[i+1] * pc[i+1]; + } + + bar (a,b,c); + + return 0; +} + +int main (void) +{ + int i; + int n=N; + + check_vect (); + main1 (n); + + return 0; +} + +/* { 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" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-6.c b/gcc/testsuite/gcc.dg/vect/vect-6.c new file mode 100644 index 000000000..5f2e0ea59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-6.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float results1[N] = {192.00,240.00,288.00,336.00,384.00,432.00,480.00,528.00,0.00}; +float results2[N] = {0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,54.00,120.00,198.00,288.00,390.00,504.00,630.00}; +float a[N] = {0}; +float e[N] = {0}; +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N/2; i++) + { + a[i] = b[i+N/2] * c[i+N/2] - b[i] * c[i]; + e[i+N/2] = b[i] * c[i+N/2] + b[i+N/2] * c[i]; + } + + /* check results: */ + for (i=0; i<N; i++) + { + if (a[i] != results1[i] || e[i] != results2[i]) + abort(); + } + + + for (i = 1; i <=N-4; i++) + { + a[i+3] = b[i-1]; + } + + /* check results: */ + for (i = 1; i <=N-4; i++) + { + if (a[i+3] != b[i-1]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-60.c b/gcc/testsuite/gcc.dg/vect/vect-60.c new file mode 100644 index 000000000..838a9bca4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-60.c @@ -0,0 +1,76 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i] != (pb[i+1] * pc[i+1])) + abort (); + } + + return; +} + +/* Unaligned pointer read accesses, aligned write access. + The loop bound is unknown + No aliasing problems. + vect-52.c is similar to this one with one difference: + the alignment of the read accesses is unknown. + vect-56.c is similar to this one with one difference: + the loop bound is known. + vect-61.c is similar to this one with two differences: + aliasing is not a problem, and the write access has unknown alignment. */ + +float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; +float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +__attribute__ ((noinline)) int +main1 (int n) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float *pa = a; + float *pb = b; + float *pc = c; + + for (i = 0; i < n/2; i++) + { + pa[i] = pb[i+1] * pc[i+1]; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (pa[i] != (pb[i+1] * pc[i+1])) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + int n=N; + + check_vect (); + main1 (n); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { xfail { vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { vect_element_align } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-62.c b/gcc/testsuite/gcc.dg/vect/vect-62.c new file mode 100644 index 000000000..724b646fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-62.c @@ -0,0 +1,70 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + int ia[N][4][N+8]; + + /* Multidimensional array. Aligned. The "inner" dimensions + are invariant in the inner loop. Store. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + ia[i][1][j+8] = ib[i]; + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i][1][j+8] != ib[i]) + abort(); + } + } + + /* Multidimensional array. Aligned. The "inner" dimensions + are invariant in the inner loop. Vectorizable, but the + vectorizer detects that everything is invariant and that + the loop is better left untouched. (it should be optimized away). */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + ia[i][1][8] = ib[i]; + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i][1][8] != ib[i]) + abort(); + } + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-63.c b/gcc/testsuite/gcc.dg/vect/vect-63.c new file mode 100644 index 000000000..70628da2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-63.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + 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++) + { + ia[i + j][1][j] = ib[i]; + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i + j][1][j] != ib[i]) + abort(); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-64.c b/gcc/testsuite/gcc.dg/vect/vect-64.c new file mode 100644 index 000000000..52131ea44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-64.c @@ -0,0 +1,86 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + int ia[N][4][N+1]; + int ic[N][N][3][N+1]; + int id[N][N][N+1]; + + /* Multidimensional array. Not aligned: vectorizable. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + ia[i][1][j] = ib[i]; + } + } + + /* Multidimensional array. Aligned: vectorizable. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + ic[i][1][1][j] = ib[i]; + } + } + + /* Multidimensional array. Not aligned: vectorizable. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + id[i][1][j+1] = ib[i]; + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i][1][j] != ib[i]) + abort(); + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ic[i][1][1][j] != ib[i]) + abort(); + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (id[i][1][j+1] != ib[i]) + abort(); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-65.c b/gcc/testsuite/gcc.dg/vect/vect-65.c new file mode 100644 index 000000000..ba3ab3a9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-65.c @@ -0,0 +1,83 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define M 4 + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + int ib[M][M][N] = {{{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}, + {{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}, + {{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}, + {{0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}, + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}}}; + int ia[M][M][N]; + int ic[N]; + + /* Multidimensional array. Aligned. The "inner" dimensions + are invariant in the inner loop. Load and store. */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + ia[i][1][j] = ib[2][i][j]; + } + } + + /* check results: */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i][1][j] != ib[2][i][j]) + abort(); + } + } + + /* Multidimensional array. Aligned. The "inner" dimensions + are invariant in the inner loop. Load. */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + ic[j] = ib[2][i][j]; + } + } + + /* check results: */ + for (i = 0; i < M; i++) + { + for (j = 0; j < N; j++) + { + if (ic[j] != ib[2][i][j]) + abort(); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-66.c b/gcc/testsuite/gcc.dg/vect/vect-66.c new file mode 100644 index 000000000..e0b23cd65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-66.c @@ -0,0 +1,96 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +void main1 () +{ + int i, j; + int ia[8][5][N+2]; + + /* Multidimensional array. Aligned. */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + ia[2][6][j] = 5; + } + } + + /* check results: */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + if (ia[2][6][j] != 5) + abort(); + } + } +} + +__attribute__ ((noinline)) +void main2 () +{ + int i, j; + int ia[8][5][N+2]; + + /* Multidimensional array. Aligned. */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + ia[3][6][j+2] = 5; + } + + /* check results: */ + for (i = 0; i < 16; i++) + { + for (j = 2; j < N+2; j++) + { + if (ia[3][6][j] != 5) + abort(); + } + } +} + +__attribute__ ((noinline)) +void main3 () +{ + int i, j; + int ic[16][16][5][N+2]; + + /* Multidimensional array. Not aligned. */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + ic[2][1][6][j+1] = 5; + } + } + + /* check results: */ + for (i = 0; i < 16; i++) + { + for (j = 0; j < N; j++) + { + if (ic[2][1][6][j+1] != 5) + abort(); + } + } +} + +int main (void) +{ + check_vect (); + + main1 (); + main2 (); + main3 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-67.c b/gcc/testsuite/gcc.dg/vect/vect-67.c new file mode 100644 index 000000000..1ddab5c2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-67.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 (int a, int b) +{ + int i, j; + int ia[N][4][N+8]; + + /* Multidimensional array. Aligned. The "inner" dimensions + are invariant in the inner loop. Store. + Not vectorizable: unsupported operation. */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + ia[i][1][j+8] = (a == b); + } + } + + /* check results: */ + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + if (ia[i][1][j+8] != (a == b)) + abort(); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (2 ,7); +} + +/* { 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-68.c b/gcc/testsuite/gcc.dg/vect/vect-68.c new file mode 100644 index 000000000..c4f8857ba --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-68.c @@ -0,0 +1,89 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +struct s{ + int m; + int n[N][N][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e; /* array e.n is aligned */ +}; + +__attribute__ ((noinline)) +int main1 () +{ + int i,j; + struct test1 tmp1; + + /* 1. unaligned */ + for (i = 0; i < N; i++) + { + tmp1.a.n[1][2][i] = 5; + } + + /* check results: */ + for (i = 0; i <N; i++) + { + if (tmp1.a.n[1][2][i] != 5) + abort (); + } + + /* 2. aligned */ + for (i = 3; i < N-1; i++) + { + tmp1.a.n[1][2][i] = 6; + } + + /* check results: */ + for (i = 3; i < N-1; i++) + { + if (tmp1.a.n[1][2][i] != 6) + abort (); + } + + /* 3. aligned */ + for (i = 0; i < N; i++) + { + tmp1.e.n[1][2][i] = 7; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (tmp1.e.n[1][2][i] != 7) + abort (); + } + + /* 4. unaligned */ + for (i = 3; i < N-3; i++) + { + tmp1.e.n[1][2][i] = 8; + } + + /* check results: */ + for (i = 3; i <N-3; i++) + { + if (tmp1.e.n[1][2][i] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-7.c b/gcc/testsuite/gcc.dg/vect/vect-7.c new file mode 100644 index 000000000..7a6eb6180 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-7.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +short sa[N]; +short sb[N]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + sb[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (sb[i] != 5) + abort (); + } + + for (i = 0; i < N; i++) + { + sa[i] = sb[i] + 100; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (sa[i] != 105) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-70.c b/gcc/testsuite/gcc.dg/vect/vect-70.c new file mode 100644 index 000000000..24677c2f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-70.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 24 + +struct s{ + int m; + int n[N/6][N/6][N]; +}; + +struct test1{ + struct s a; /* array a.n is unaligned */ + int b; + int c; + struct s e[N]; /* array e.n is aligned */ +}; + +__attribute__ ((noinline)) +int main1 () +{ + int i,j; + struct test1 tmp1; + + for (i = 0; i < N; i++) + for (j = 3; j < N-3; j++) + { + tmp1.e[i].n[1][2][j] = 8; + } + + /* check results: */ + for (i = 0; i < N; i++) + for (j = 3; j < N-3; j++) + { + if (tmp1.e[i].n[1][2][j] != 8) + abort (); + } + + /* not consecutive */ + for (i = 0; i < N; i++) + for (j = 3; j < N-3; j++) + { + tmp1.e[j].n[1][2][j] = 8; + } + + /* check results: */ + for (i = 0; i < N; i++) + for (j = 3; j < N-3; j++) + { + if (tmp1.e[j].n[1][2][j] != 8) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-71.c b/gcc/testsuite/gcc.dg/vect/vect-71.c new file mode 100644 index 000000000..7416b4333 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-71.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +/* indirect access. */ + +__attribute__ ((noinline)) +int main1 () +{ + int i; + unsigned ia[N]; + unsigned ib[N+1] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2}; + + for (i = 2; i < N+1; i++) + { + ia[ib[i]] = 0; + } + + /* check results: */ + for (i = 2; i < N+1; i++) + { + if (ia[ib[i]] != 0) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-72.c b/gcc/testsuite/gcc.dg/vect/vect-72.c new file mode 100644 index 000000000..67a197519 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-72.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +/* unaligned load. */ + +char ia[N]; +char ib[N+1]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + for (i=0; i < N+1; i++) + { + ib[i] = i; + /* Avoid vectorization. */ + if (i%3 == 0) + ib[i] = 5; + } + + for (i = 1; i < N+1; i++) + { + ia[i-1] = ib[i]; + } + + /* check results: */ + for (i = 1; i <= N; i++) + { + if (ia[i-1] != ib[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-73.c b/gcc/testsuite/gcc.dg/vect/vect-73.c new file mode 100644 index 000000000..ee3c6e60e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-73.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int ic[N*2]; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +#define ia (ic+N) + +__attribute__ ((noinline)) +int main1 () +{ + int i, j; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-74.c b/gcc/testsuite/gcc.dg/vect/vect-74.c new file mode 100644 index 000000000..a680b9fb0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-74.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float b[N+4] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0}; +float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 7.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5}; + +__attribute__ ((noinline)) int +main1 (float *__restrict__ pa, float * __restrict__ pb, float * __restrict__ pc) +{ + int i; + float *q = pb + 4; + + for (i = 0; i < N; i++) + { + pa[i] = q[i] * pc[i]; + } + + for (i = 0; i < N; i++) + { + if (pa[i] != q[i] * pc[i]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (a, b, c); + + return 0; +} + +/* Xfail until handling restrict is refined. See pr29145 */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* Uncomment when this testcase gets vectorized again: + dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } + dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } + dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } +*/ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-75.c b/gcc/testsuite/gcc.dg/vect/vect-75.c new file mode 100644 index 000000000..092a3013e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-75.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +#define OFF 8 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 14, 22, 26, 34}; + +__attribute__ ((noinline)) +int main1 (int *ib) +{ + int i; + int ia[N]; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+OFF]; + } + + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+OFF]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (ib); + return 0; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-76.c b/gcc/testsuite/gcc.dg/vect/vect-76.c new file mode 100644 index 000000000..d77130242 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-76.c @@ -0,0 +1,74 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 24 +#define OFF 4 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; +int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10}; + +__attribute__ ((noinline)) +int main1 (int *pib) +{ + int i; + int ia[N+OFF]; + + for (i = OFF; i < N; i++) + { + ia[i] = pib[i - OFF]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (ia[i] != pib[i - OFF]) + abort (); + } + + for (i = 0; i < N; i++) + { + ia[i] = pib[i - OFF]; + } + + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != pib[i - OFF]) + abort (); + } + + for (i = OFF; i < N; i++) + { + ia[i] = ic[i - OFF]; + } + + + /* check results: */ + for (i = OFF; i < N; i++) + { + if (ia[i] != ic[i - OFF]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (&ib[OFF]); + return 0; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-77-alignchecks.c b/gcc/testsuite/gcc.dg/vect/vect-77-alignchecks.c new file mode 100644 index 000000000..4a05874b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-77-alignchecks.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +#define OFF 8 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 14, 22, 26, 34}; + +__attribute__ ((noinline)) +int main1 (int *ib, int off) +{ + int i; + int ia[N]; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+off]; + } + + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+off]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (ib, 8); + return 0; +} + +/* For targets that don't support misaligned loads we version for the load. + The store is aligned if alignment can be forced on the stack. Otherwise, we need to + peel the loop in order to align the store. For targets that can't align variables + using peeling (don't guarantee natural alignment) versioning the loop is required + both for the load and the store. */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { {! vect_no_align} && { unaligned_stack && vector_alignment_reachable } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { { {! unaligned_stack} && vect_no_align } || {unaligned_stack && { {! vector_alignment_reachable} && {! vect_no_align} } } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { { unaligned_stack && { vector_alignment_reachable && vect_no_align } } || {unaligned_stack && { {! vector_alignment_reachable} && vect_no_align } } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-77-global.c b/gcc/testsuite/gcc.dg/vect/vect-77-global.c new file mode 100644 index 000000000..ac29d7d3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-77-global.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +#define OFF 8 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 14, 22, 26, 34}; +int ia[N]; + +__attribute__ ((noinline)) +int main1 (int *ib, int off) +{ + int i; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+off]; + } + + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+off]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (ib, 8); + return 0; +} + +/* For targets that don't support misaligned loads we version for the load. + (The store is aligned). */ +/* Requires versioning for aliasing. */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-77.c b/gcc/testsuite/gcc.dg/vect/vect-77.c new file mode 100644 index 000000000..07ee0fde1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-77.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +#define OFF 8 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 14, 22, 26, 34}; + +__attribute__ ((noinline)) +int main1 (int *ib, int off) +{ + int i; + int ia[N]; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+off]; + } + + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+off]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (ib, 8); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-78-alignchecks.c b/gcc/testsuite/gcc.dg/vect/vect-78-alignchecks.c new file mode 100644 index 000000000..71c01ae1c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-78-alignchecks.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +#define OFF 8 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 14, 22, 26, 34}; +int off = 8; + +__attribute__ ((noinline)) +int main1 (int *ib) +{ + int i; + int ia[N]; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+off]; + } + + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+off]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (ib); + return 0; +} + +/* For targets that don't support misaligned loads we version for the load. + The store is aligned if alignment can be forced on the stack. Otherwise, we need to + peel the loop in order to align the store. For targets that can't align variables + using peeling (don't guarantee natural alignment) versioning the loop is required + both for the load and the store. */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { {! vect_no_align} && { unaligned_stack && vector_alignment_reachable } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { { {! unaligned_stack} && vect_no_align } || {unaligned_stack && { {! vector_alignment_reachable} && {! vect_no_align} } } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { { unaligned_stack && { vector_alignment_reachable && vect_no_align } } || {unaligned_stack && { {! vector_alignment_reachable} && vect_no_align } } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-78-global.c b/gcc/testsuite/gcc.dg/vect/vect-78-global.c new file mode 100644 index 000000000..ec6520fd8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-78-global.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +#define OFF 8 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ia[N]; +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 14, 22, 26, 34}; +int off = 8; + +__attribute__ ((noinline)) +int main1 (int *ib) +{ + int i; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+off]; + } + + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+off]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (ib); + return 0; +} + +/* For targets that don't support misaligned loads we version for the load. + (The store is aligned). */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-78.c b/gcc/testsuite/gcc.dg/vect/vect-78.c new file mode 100644 index 000000000..12ea12af9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-78.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 +#define OFF 8 + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10, 14, 22, 26, 34}; +int off = 8; + +__attribute__ ((noinline)) +int main1 (int *ib) +{ + int i; + int ia[N]; + + for (i = 0; i < N; i++) + { + ia[i] = ib[i+off]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i+off]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (ib); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-8.c b/gcc/testsuite/gcc.dg/vect/vect-8.c new file mode 100644 index 000000000..62f819e04 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-8.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float b[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; +float a[N]; + +__attribute__ ((noinline)) +int main1 (int n) +{ + int i; + + /* Vectorized: unknown loop bound). */ + for (i = 0; i < n; i++){ + a[i] = b[i]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (a[i] != b[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (N); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-80.c b/gcc/testsuite/gcc.dg/vect/vect-80.c new file mode 100644 index 000000000..fc0ed1b39 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-80.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float fa[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float fb[N+4] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 7.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0}; +float fc[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 7.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5, 15.5}; + +/* Check handling of accesses for which the "initial condition" - + the expression that represents the first location accessed - is + more involved than just an ssa_name. */ + +__attribute__ ((noinline)) int +main1 (float * __restrict__ pa, float * __restrict__ pb, float *__restrict__ pc) +{ + int i; + float *q = pb + 4; + + for (i = 0; i < N; i++) + { + pa[i] = q[i] * pc[i]; + } + + for (i = 0; i < N; i++) + { + if (pa[i] != q[i] * pc[i]) + abort(); + } + + return 0; +} + + +int main (void) +{ + check_vect (); + + main1 (fa, fb, fc); + + return 0; +} + +/* For targets that don't support misaligned loads we version for the + all three accesses (peeling to align the store will not force the + two loads to be aligned). */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* Uncomment when this testcase gets vectorized again: + dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } + dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } + dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } +*/ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-82.c b/gcc/testsuite/gcc.dg/vect/vect-82.c new file mode 100644 index 000000000..7fbaa9216 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-82.c @@ -0,0 +1,37 @@ +/* { dg-skip-if "powerpc and integer vectorization only" { ! { powerpc*-*-* && vect_int } } { "*" } { "" } } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + long long unsigned int ca[N]; + int i; + + for (i = 0; i < N; i++) + { + ca[i] = 0; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != 0) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-82_64.c b/gcc/testsuite/gcc.dg/vect/vect-82_64.c new file mode 100644 index 000000000..71de0ce2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-82_64.c @@ -0,0 +1,39 @@ +/* { dg-do run { target { { powerpc*-*-* && lp64 } && powerpc_altivec_ok } } } */ +/* { dg-do compile { target { { powerpc*-*-* && ilp32 } && powerpc_altivec_ok } } } */ +/* { dg-options "-O2 -ftree-vectorize -mpowerpc64 -fdump-tree-vect-stats -maltivec" } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + long long unsigned int ca[N]; + int i; + + for (i = 0; i < N; i++) + { + ca[i] = 0; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != 0) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-83.c b/gcc/testsuite/gcc.dg/vect/vect-83.c new file mode 100644 index 000000000..c031db9df --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-83.c @@ -0,0 +1,37 @@ +/* { dg-skip-if "powerpc and integer vectorization only" { ! { powerpc*-*-* && vect_int } } { "*" } { "" } } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + long long unsigned int ca[N]; + int i; + + for (i = 0; i < N; i++) + { + ca[i] = 2; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != 2) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-83_64.c b/gcc/testsuite/gcc.dg/vect/vect-83_64.c new file mode 100644 index 000000000..8734a5271 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-83_64.c @@ -0,0 +1,39 @@ +/* { dg-do run { target { { powerpc*-*-* && lp64 } && powerpc_altivec_ok } } } */ +/* { dg-do compile { target { { powerpc*-*-* && ilp32 } && powerpc_altivec_ok } } } */ +/* { dg-options "-O2 -ftree-vectorize -mpowerpc64 -fdump-tree-vect-stats -maltivec" } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + long long unsigned int ca[N]; + int i; + + for (i = 0; i < N; i++) + { + ca[i] = 2; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != 2) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-85.c b/gcc/testsuite/gcc.dg/vect/vect-85.c new file mode 100644 index 000000000..a5bf5db07 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-85.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 (int *a) +{ + int i, j, k; + int b[N]; + + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + k = i + N; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < N; j++) + if (a[j] != i + N - 1) + abort(); + + for (j = 0; j < N; j++) + if (b[j] != j + N) + abort(); + + return 0; +} + +int main (void) +{ + int a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + check_vect (); + + main1 (a); + + return 0; +} + +/* Fails for targets that don't vectorize PLUS (e.g alpha). */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-86.c b/gcc/testsuite/gcc.dg/vect/vect-86.c new file mode 100644 index 000000000..334e54ee4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-86.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int a[N]; + +__attribute__ ((noinline)) +int main1 (int n) +{ + int i, j, k; + int b[N]; + + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + k = i + n; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < n; j++) + if (a[j] != i + n - 1) + abort(); + + for (i = 0; i < n; i++) + if (b[i] != i + n) + abort(); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N); + main1 (0); + main1 (1); + main1 (2); + main1 (N-1); + + return 0; +} + +/* Fails for targets that don't vectorize PLUS (e.g alpha). */ +/* { 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" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-87.c b/gcc/testsuite/gcc.dg/vect/vect-87.c new file mode 100644 index 000000000..9912f19e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-87.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 (int n, int *a) +{ + int i, j, k; + int b[N]; + + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + k = i + n; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < n; j++) + if (a[j] != i + n - 1) + abort(); + + for (j = 0; j < n; j++) + if (b[j] != j + n) + abort(); + + return 0; +} + +int main (void) +{ + int a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + check_vect (); + + main1 (N, a); + main1 (0, a); + main1 (1, a); + main1 (2, a); + main1 (N-1, a); + + return 0; +} + +/* Fails for targets that don't vectorize PLUS (e.g alpha). */ +/* { 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} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-88.c b/gcc/testsuite/gcc.dg/vect/vect-88.c new file mode 100644 index 000000000..593854652 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-88.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 (int n, int *a) +{ + int i, j, k; + int b[N]; + + for (i = 0; i < n; i++) + { + for (j = 0; j < n; j++) + { + k = i + n; + a[j] = k; + } + b[i] = k; + } + + + for (j = 0; j < n; j++) + if (a[j] != i + n - 1) + abort(); + + for (j = 0; j < n; j++) + if (b[j] != j + n) + abort(); + + return 0; +} + +int main (void) +{ + int a[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + check_vect (); + + main1 (N, a+1); + main1 (0, a+1); + main1 (1, a+1); + main1 (2, a+1); + main1 (N-1, a+1); + + return 0; +} + +/* Fails for targets that don't vectorize PLUS (e.g alpha). */ +/* { 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} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-89.c b/gcc/testsuite/gcc.dg/vect/vect-89.c new file mode 100644 index 000000000..131efeab5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-89.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct tmp_struct +{ + int x; + int y[N]; +}; + +__attribute__ ((noinline)) +int main1 () +{ + int i, *q; + struct tmp_struct tmp, *p; + + p = &tmp; + q = p->y; + + for (i = 0; i < N; i++) + { + *q++ = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->y[i] != 5) + { + abort (); + } + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-9.c b/gcc/testsuite/gcc.dg/vect/vect-9.c new file mode 100644 index 000000000..c11784a4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-9.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ia[N]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + /* Requires type promotion (vector unpacking) support. */ + for (i = 0; i < N; i++) + { + ia[i] = (int) sb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != (int) sb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-91.c b/gcc/testsuite/gcc.dg/vect/vect-91.c new file mode 100644 index 000000000..619c8edd7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-91.c @@ -0,0 +1,64 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +extern int a[N+20]; + +/* The alignment of 'pa' is unknown. + Yet we do know that both the read access and write access have + the same alignment. Peeling to align one of the accesses will + align the other. */ + +__attribute__ ((noinline)) int +main1 (int * pa) +{ + int i; + + for (i = 0; i < N; i++) + { + pa[i] = pa[i] + 1; + } + + return 0; +} + +/* The alignment of 'a' is unknown. + Yet we do know that both the read access and write access have + the same alignment. Peeling to align one of the accesses will + align the other. */ + +__attribute__ ((noinline)) int +main2 () +{ + int i; + + for (i = 0; i < N; i++) + { + a[i] = a[i] + 1; + } + + return 0; +} + +__attribute__ ((noinline)) int +main3 () +{ + int i; + + for (i = 0; i < N; i++) + { + a[i] = a[i+20]; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 3 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" {target { vector_alignment_reachable } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" {target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-92.c b/gcc/testsuite/gcc.dg/vect/vect-92.c new file mode 100644 index 000000000..3a64e251c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-92.c @@ -0,0 +1,96 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +float pa[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float pb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; +float pc[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + +/* Check handling of unaligned accesses when the misalignment is + known at compile time and different accesses have the same + misalignment (e.g. peeling to align one access will align all + accesses with the same misalignment. Also, the number of + peeled iterations is known in this case, and the vectorizer + can use this information (generate prolog and epilog loops + with known number of iterations, and only if needed). */ + +__attribute__ ((noinline)) int +main1 () +{ + int i; + + for (i = 0; i < 10; i++) + { + pa[i+1] = pb[i+1] * pc[i+1]; + } + + /* check results: */ + for (i = 0; i < 10; i++) + { + if (pa[i+1] != (pb[i+1] * pc[i+1])) + abort (); + } + + return 0; +} + +__attribute__ ((noinline)) int +main2 () +{ + int i; + + for (i = 0; i < 12; i++) + { + pa[i+1] = pb[i+1] * pc[i+1]; + } + + /* check results: */ + for (i = 0; i < 12; i++) + { + if (pa[i+1] != (pb[i+1] * pc[i+1])) + abort (); + } + + return 0; +} + +__attribute__ ((noinline)) int +main3 (int n) +{ + int i; + + for (i = 0; i < n; i++) + { + pa[i+1] = pb[i+1] * pc[i+1]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (pa[i+1] != (pb[i+1] * pc[i+1])) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + main1 (); + main2 (); + main3 (N-1); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "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" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-93.c b/gcc/testsuite/gcc.dg/vect/vect-93.c new file mode 100644 index 000000000..65403eb72 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-93.c @@ -0,0 +1,85 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 3001 + + +__attribute__ ((noinline)) +main1 (float *pa) +{ + int i; + + for (i = 0; i < 3001; i++) + { + pa[i] = 2.0; + } + + /* check results: */ + for (i = 0; i < 3001; i++) + { + if (pa[i] != 2.0) + abort (); + } + + for (i = 1; i <= 10; i++) + { + pa[i] = 3.0; + } + + /* check results: */ + for (i = 1; i <= 10; i++) + { + if (pa[i] != 3.0) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + + check_vect (); + + /* from bzip2: */ + for (i=0; i<N; i++) b[i] = i; + a[0] = 0; + for (i = 1; i <= 256; i++) a[i] = b[i-1]; + + /* check results: */ + for (i = 1; i <= 256; i++) + { + if (a[i] != i-1) + abort (); + } + if (a[0] != 0) + abort (); + + main1 (a); + + return 0; +} + +/* 2 loops vectorized in main1, 2 loops vectorized in main: + the first loop in main requires vectorization of conversions, + the second loop in main requires vectorization of misaligned load. */ + +/* main && main1 together: */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 2 "vect" { target powerpc*-*-* i?86-*-* x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { vect_no_align && {! vector_alignment_reachable} } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { { vect_no_align } || { { ! vector_alignment_reachable} || vect_element_align } } } } } */ + +/* in main1: */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target !powerpc*-*-* !i?86-*-* !x86_64-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target vect_no_align } } } */ + +/* in main: */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-95.c b/gcc/testsuite/gcc.dg/vect/vect-95.c new file mode 100644 index 000000000..c03d1965d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-95.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 256 + +__attribute__ ((noinline)) +void bar (float *pd, float *pa, float *pb, float *pc) +{ + int i; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pa[i] != (pb[i] * pc[i])) + abort (); + if (pd[i] != 5.0) + abort (); + } + + return; +} + + +__attribute__ ((noinline)) int +main1 (int n, float * __restrict__ pd, float * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc) +{ + int i; + + for (i = 0; i < n; i++) + { + pa[i] = pb[i] * pc[i]; + pd[i] = 5.0; + } + + bar (pd,pa,pb,pc); + + return 0; +} + +int main (void) +{ + int i; + float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float d[N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; + + check_vect (); + + main1 (N,&d[1],a,b,c); + main1 (N-2,&d[1],a,b,c); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { xfail {vect_element_align} } } } */ + +/* For targets that support unaligned loads we version for the two unaligned + stores and generate misaligned accesses for the loads. For targets that + don't support unaligned loads we version for all four accesses. */ + +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_element_align} } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 4 "vect" { target vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-96.c b/gcc/testsuite/gcc.dg/vect/vect-96.c new file mode 100644 index 000000000..049ac2434 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-96.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct tmp +{ + int x; + int ia[N]; +}; + +__attribute__ ((noinline)) +int main1 (int off) +{ + struct tmp sb[N]; + struct tmp *pp = &sb[off]; + int i, ib[N]; + + for (i = 0; i < N; i++) + pp->ia[i] = ib[i]; + + /* check results: */ + for (i = 0; i < N; i++) + { + if (pp->ia[i] != ib[i]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (8); +} + +/* The store is unaligned, the load is aligned. For targets that support unaligned + loads, peel to align the store and generate an unaligned access for the load. + For targets that don't support unaligned loads, version for the store. */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { {! vect_no_align} && vector_alignment_reachable } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align } || { { ! vector_alignment_reachable} || vect_element_align } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { vect_no_align || { {! vector_alignment_reachable} && {! vect_element_align} } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-97.c b/gcc/testsuite/gcc.dg/vect/vect-97.c new file mode 100644 index 000000000..6ea261490 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-97.c @@ -0,0 +1,65 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +char x[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +char cb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 () +{ + struct { + char *p; + char *q; + } s; + int i; + + /* Check that datarefs analysis can determine that the access via pointer + s.p is based off array x, which enables us to antialias this access from + the access to array cb. */ + s.p = x; + for (i = 0; i < N; i++) + { + s.p[i] = cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.p[i] != cb[i]) + abort (); + } + + /* Check that datarefs analysis can determine that the access via pointer + s.p is based off array x, and that the access via pointer s.q is based off + array cb, which enables us to antialias these two accesses. */ + s.q = cb; + for (i = 0; i < N; i++) + { + s.p[i] = s.q[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (s.p[i] != s.q[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-98.c b/gcc/testsuite/gcc.dg/vect/vect-98.c new file mode 100644 index 000000000..118f28fd3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-98.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 4 +#define DOT4( a, b ) ( a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3] ) + +__attribute__ ((noinline)) +int main1 (int ia[][N]) +{ + int i, j; + int ib[N] = {0,3,6,9}; + int ic[N][N]; + + for (i = 0; i < N; i++) + { + ic[0][i] = DOT4 (ia[i], ib); + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ic[0][i] != DOT4 (ia[i], ib)) + abort(); + } + + return 0; +} + +int main (void) +{ + int ia[N][N] = {{1,2,3,4},{2,3,5,7},{2,4,6,8},{22,43,55,77}}; + + check_vect (); + + return main1 (ia); +} + +/* Needs interleaving support. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd_wide } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { xfail { vect_interleave && vect_extract_even_odd_wide } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-99.c b/gcc/testsuite/gcc.dg/vect/vect-99.c new file mode 100644 index 000000000..d29023c73 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-99.c @@ -0,0 +1,33 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include "tree-vect.h" + +int ca[100]; + +__attribute__ ((noinline)) +void foo (int n) +{ + unsigned int i; + + for (i = 0; i < n; i++) + ca[i] = 2; +} + +int main (void) +{ + int i; + + check_vect (); + + foo(100); + + for (i = 0; i < 100; ++i) { + if (ca[i] != 2) + abort(); + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-align-1.c b/gcc/testsuite/gcc.dg/vect/vect-align-1.c new file mode 100644 index 000000000..099b7fea4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-align-1.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +/* Compile time known misalignment. Cannot use loop peeling to align + the store. */ + +#define N 16 + +struct foo { + char x; + int y[N]; +} __attribute__((packed)); + +int x[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) int +main1 (struct foo * __restrict__ p) +{ + int i; + + for (i = 0; i < N; i++) + { + p->y[i] = x[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (p->y[i] != x[i]) + abort (); + } + return 0; +} + + +int main (void) +{ + int i; + struct foo *p = malloc (2*sizeof (struct foo)); + check_vect (); + + main1 (p); + return 0; +} + +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target vect_hw_misalign } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { xfail vect_hw_misalign} } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-align-2.c b/gcc/testsuite/gcc.dg/vect/vect-align-2.c new file mode 100644 index 000000000..08a80112d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-align-2.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdlib.h> +#include <stdarg.h> +#include "tree-vect.h" + +/* Compile time unknown misalignment. Cannot use loop peeling to align + the store. */ + +#define N 17 + +struct foo { + char x0; + int y[N][N]; +} __attribute__ ((packed)); + +struct foo f2; +int z[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) +void fbar(struct foo *fp) +{ + int i,j; + for (i=0; i<N; i++) + for (j=0; j<N; j++) + f2.y[i][j] = z[i]; + + for (i=0; i<N; i++) + for (j=0; j<N; j++) + if (f2.y[i][j] != z[i]) + abort (); +} + +int main (void) +{ + struct foo *fp = (struct foo *) malloc (2*sizeof (struct foo)); + + check_vect (); + + fbar(fp); + return 0; +} + + +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { xfail vect_hw_misalign} } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-all.c b/gcc/testsuite/gcc.dg/vect/vect-all.c new file mode 100644 index 000000000..6adb7bf88 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-all.c @@ -0,0 +1,220 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int iadd_results[N] = {0,6,12,18,24,30,36,42,48,54,60,66,72,78,84,90}; +float fadd_results[N] = {0.0,6.0,12.0,18.0,24.0,30.0,36.0,42.0,48.0,54.0,60.0,66.0,72.0,78.0,84.0,90.0}; +float fmul_results[N] = {0.0,3.0,12.0,27.0,48.0,75.0,108.0,147.0,192.0,243.0,300.0,363.0,432.0,507.0,588.0,675.0}; +float fresults1[N] = {192.00,240.00,288.00,336.00,384.00,432.00,480.00,528.00,48.00,54.00,60.00,66.00,72.00,78.00,84.00,90.00}; +float fresults2[N] = {0.00,6.00,12.00,18.00,24.00,30.00,36.00,42.00,0.00,54.00,120.00,198.00,288.00,390.00,504.00,630.00}; + +/****************************************************/ +__attribute__ ((noinline)) +void icheck_results (int *a, int *results) +{ + int i; + for (i = 0; i < N; i++) + { + if (a[i] != results[i]) + abort (); + } +} + +__attribute__ ((noinline)) +void fcheck_results (float *a, float *results) +{ + int i; + for (i = 0; i < N; i++) + { + if (a[i] != results[i]) + abort (); + } +} + +__attribute__ ((noinline)) void +fbar_mul (float *a) +{ + fcheck_results (a, fmul_results); +} + +__attribute__ ((noinline)) void +fbar_add (float *a) +{ + fcheck_results (a, fadd_results); +} + +__attribute__ ((noinline)) void +ibar_add (int *a) +{ + icheck_results (a, iadd_results); +} + +__attribute__ ((noinline)) void +fbar1 (float *a) +{ + fcheck_results (a, fresults1); +} + +__attribute__ ((noinline)) void +fbar2 (float *a) +{ + fcheck_results (a, fresults2); +} + +float a[N]; +float e[N]; +float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; +int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int ia[N]; +char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +char ca[N]; +short sa[N]; + +/* All of the loops below are currently vectorizable. */ + +__attribute__ ((noinline)) int +main1 () +{ + int i,j; + + /* Test 1: copy chars. */ + for (i = 0; i < N; i++) + { + ca[i] = cb[i]; + } + /* check results: */ + for (i = 0; i < N; i++) + { + if (ca[i] != cb[i]) + abort (); + } + + + /* Test 2: fp mult. */ + for (i = 0; i < N; i++) + { + a[i] = b[i] * c[i]; + } + fbar_mul (a); + + + /* Test 3: mixed types (int, fp), same nunits in vector. */ + for (i = 0; i < N; i++) + { + a[i] = b[i] + c[i] + d[i]; + e[i] = b[i] + c[i] + d[i]; + ia[i] = ib[i] + ic[i]; + } + ibar_add (ia); + fbar_add (a); + fbar_add (e); + + + /* Test 4: access with offset. */ + for (i = 0; i < N/2; i++) + { + a[i] = b[i+N/2] * c[i+N/2] - b[i] * c[i]; + e[i+N/2] = b[i] * c[i+N/2] + b[i+N/2] * c[i]; + } + fbar1 (a); + fbar2 (e); + + + /* Test 5: access with offset */ + for (i = 1; i <=N-4; i++) + { + a[i+3] = b[i-1]; + } + /* check results: */ + for (i = 1; i <=N-4; i++) + { + if (a[i+3] != b[i-1]) + abort (); + } + + + /* Test 6 - loop induction with stride != 1. */ + i = 0; + j = 0; + while (i < 5*N) + { + a[j] = c[j]; + i += 5; + j++; + } + /* check results: */ + for (i = 0; i <N; i++) + { + if (a[i] != c[i]) + abort (); + } + + + /* Test 7 - reverse access. */ + for (i = N; i > 0; i--) + { + a[N-i] = d[N-i]; + } + /* check results: */ + for (i = 0; i <N; i++) + { + if (a[i] != d[i]) + abort (); + } + + + /* Tests 8,9,10 - constants. */ + for (i = 0; i < N; i++) + { + a[i] = 5.0; + } + /* check results: */ + for (i = 0; i < N; i++) + { + if (a[i] != 5.0) + abort (); + } + + for (i = 0; i < N; i++) + { + sa[i] = 5; + } + /* check results: */ + for (i = 0; i < N; i++) + { + if (sa[i] != 5) + abort (); + } + + for (i = 0; i < N; i++) + { + ia[i] = ib[i] + 5; + } + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i] + 5) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 10 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" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-1.c b/gcc/testsuite/gcc.dg/vect/vect-complex-1.c new file mode 100644 index 000000000..23f3651eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-complex-1.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +_Complex float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + { 10.0F + 20.0iF, 11.0F + 21.0iF, 12.0F + 22.0iF, 13.0F + 23.0iF, + 14.0F + 24.0iF, 15.0F + 25.0iF, 16.0F + 26.0iF, 17.0F + 27.0iF, + 18.0F + 28.0iF, 19.0F + 29.0iF, 20.0F + 30.0iF, 21.0F + 31.0iF, + 22.0F + 32.0iF, 23.0F + 33.0iF, 24.0F + 34.0iF, 25.0F + 35.0iF }; +_Complex float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + { 30.0F + 40.0iF, 31.0F + 41.0iF, 32.0F + 42.0iF, 33.0F + 43.0iF, + 34.0F + 44.0iF, 35.0F + 45.0iF, 36.0F + 46.0iF, 37.0F + 47.0iF, + 38.0F + 48.0iF, 39.0F + 49.0iF, 40.0F + 50.0iF, 41.0F + 51.0iF, + 42.0F + 52.0iF, 43.0F + 53.0iF, 44.0F + 54.0iF, 45.0F + 55.0iF }; + +_Complex float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +_Complex float res[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + { 40.0F + 60.0iF, 42.0F + 62.0iF, 44.0F + 64.0iF, 46.0F + 66.0iF, + 48.0F + 68.0iF, 50.0F + 70.0iF, 52.0F + 72.0iF, 54.0F + 74.0iF, + 56.0F + 76.0iF, 58.0F + 78.0iF, 60.0F + 80.0iF, 62.0F + 82.0iF, + 64.0F + 84.0iF, 66.0F + 86.0iF, 68.0F + 88.0iF, 70.0F + 90.0iF }; + + +__attribute__ ((noinline)) void +foo (void) +{ + int i; + + for (i = 0; i < N; i++) + c[i] = a[i] + b[i]; + +} + +int +main (void) +{ + int i; + check_vect (); + + foo (); + + /* check results: */ + for (i = 0; i < N; i++) + if (c[i] != res[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-2.c b/gcc/testsuite/gcc.dg/vect/vect-complex-2.c new file mode 100644 index 000000000..498e742a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-complex-2.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +_Complex double a[N] = + { 10.0F + 20.0iF, 11.0F + 21.0iF, 12.0F + 22.0iF, 13.0F + 23.0iF, + 14.0F + 24.0iF, 15.0F + 25.0iF, 16.0F + 26.0iF, 17.0F + 27.0iF, + 18.0F + 28.0iF, 19.0F + 29.0iF, 20.0F + 30.0iF, 21.0F + 31.0iF, + 22.0F + 32.0iF, 23.0F + 33.0iF, 24.0F + 34.0iF, 25.0F + 35.0iF }; +_Complex double b[N] = + { 30.0F + 40.0iF, 31.0F + 41.0iF, 32.0F + 42.0iF, 33.0F + 43.0iF, + 34.0F + 44.0iF, 35.0F + 45.0iF, 36.0F + 46.0iF, 37.0F + 47.0iF, + 38.0F + 48.0iF, 39.0F + 49.0iF, 40.0F + 50.0iF, 41.0F + 51.0iF, + 42.0F + 52.0iF, 43.0F + 53.0iF, 44.0F + 54.0iF, 45.0F + 55.0iF }; + +_Complex double c[N]; +_Complex double res[N] = + { 40.0F + 60.0iF, 42.0F + 62.0iF, 44.0F + 64.0iF, 46.0F + 66.0iF, + 48.0F + 68.0iF, 50.0F + 70.0iF, 52.0F + 72.0iF, 54.0F + 74.0iF, + 56.0F + 76.0iF, 58.0F + 78.0iF, 60.0F + 80.0iF, 62.0F + 82.0iF, + 64.0F + 84.0iF, 66.0F + 86.0iF, 68.0F + 88.0iF, 70.0F + 90.0iF }; + + +__attribute__ ((noinline)) void +foo (void) +{ + int i; + + for (i = 0; i < N; i++) + c[i] = a[i] + b[i]; + +} + +int +main (void) +{ + int i; + check_vect (); + + foo (); + + /* check results: */ + for (i = 0; i < N; i++) + if (c[i] != res[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-4.c b/gcc/testsuite/gcc.dg/vect/vect-complex-4.c new file mode 100644 index 000000000..288ff07c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-complex-4.c @@ -0,0 +1,108 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct foostr { + _Complex short f1; + _Complex short f2; +}; + +struct foostr a[16] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + { + 11 + 23i, 24 + 22i, + 11 + 26i, 24 + 35i, + 19 + 20i, 29 + 14i, + 23 + 31i, 26 + 30i, + 29 + 39i, 24 + 18i, + 20 + 32i, 16 + 23i, + 13 + 26i, 37 + 34i, + 12 + 23i, 26 + 14i, + 36 + 14i, 31 + 17i, + 35 + 17i, 17 + 36i, + 13 + 34i, 19 + 12i, + 27 + 34i, 36 + 19i, + 21 + 39i, 16 + 33i, + 28 + 18i, 39 + 26i, + 32 + 27i, 13 + 38i, + 35 + 36i, 34 + 28i, + }; + +struct foostr b[16] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + { + 37 + 12i, 23 + 15i, + 14 + 11i, 13 + 25i, + 35 + 29i, 22 + 34i, + 24 + 34i, 16 + 39i, + 34 + 32i, 26 + 21i, + 34 + 36i, 11 + 37i, + 25 + 21i, 10 + 39i, + 10 + 36i, 35 + 22i, + 39 + 29i, 23 + 21i, + 34 + 33i, 39 + 14i, + 16 + 31i, 32 + 33i, + 20 + 14i, 35 + 30i, + 26 + 24i, 36 + 37i, + 31 + 20i, 32 + 28i, + 25 + 27i, 15 + 30i, + 10 + 31i, 37 + 37i, + }; +struct foostr c[16] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +struct foostr res[N] = + { + 48 + 35i, 47 + 37i, + 25 + 37i, 37 + 60i, + 54 + 49i, 51 + 48i, + 47 + 65i, 42 + 69i, + 63 + 71i, 50 + 39i, + 54 + 68i, 27 + 60i, + 38 + 47i, 47 + 73i, + 22 + 59i, 61 + 36i, + 75 + 43i, 54 + 38i, + 69 + 50i, 56 + 50i, + 29 + 65i, 51 + 45i, + 47 + 48i, 71 + 49i, + 47 + 63i, 52 + 70i, + 59 + 38i, 71 + 54i, + 57 + 54i, 28 + 68i, + 45 + 67i, 71 + 65i, + }; + +__attribute__ ((noinline)) void +foo (void) +{ + int i; + + for (i = 0; i < N; i++) + { + c[i].f1 = a[i].f1 + b[i].f1; + c[i].f2 = a[i].f2 + b[i].f2; + } + +} + +int +main (void) +{ + int i; + check_vect (); + + foo (); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (c[i].f1 != res[i].f1) + abort (); + if (c[i].f2 != res[i].f2) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-complex-5.c b/gcc/testsuite/gcc.dg/vect/vect-complex-5.c new file mode 100644 index 000000000..83d04cd04 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-complex-5.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +struct foostr { + _Complex short f1; + _Complex short f2; +}; + +_Complex short a1[64] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +_Complex short a2[64] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +_Complex short b1[64] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +_Complex short b2[64] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +struct foostr c[64] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo (void) +{ + int i; + + for (i = 0; i < N; i++) + { + c[i].f1 = a1[i] + b1[i]; + c[i].f2 = a2[i] + b2[i]; + } + +} + +int +main (void) +{ + int i; + check_vect (); + + foo (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-1.c b/gcc/testsuite/gcc.dg/vect/vect-cond-1.c new file mode 100644 index 000000000..e42752f97 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-1.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_condition } */ + +#include <stdlib.h> +#include "tree-vect.h" + +#define M 32 +#define N 16 + +int x_in[M]; +int x_out[M]; +int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2}; +int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024}; +int check_result[M] = {1024,1024,1024,256,256,256,256,256,256,256,256,128,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48}; + +__attribute__ ((noinline)) void +foo () +{ + int j, i, x; + int curr_a, next_a; + + for (j = 0; j < M; j++) + { + x = x_in[j]; + curr_a = a[0]; + + for (i = 0; i < N; i++) + { + next_a = a[i+1]; + curr_a = x > c[i] ? curr_a : next_a; + } + + x_out[j] = curr_a; + } +} + +int main (void) +{ + int i,j; + + check_vect (); + + for (j = 0; j < M; j++) + x_in[j] = j; + + foo (); + + for (j = 0; j < M; j++) + if (x_out[j] != check_result[j]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-2.c b/gcc/testsuite/gcc.dg/vect/vect-cond-2.c new file mode 100644 index 000000000..97d3241a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-2.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_condition } */ + +#include <stdlib.h> +#include "tree-vect.h" + +#define N 16 + +int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2}; +int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024}; + +__attribute__ ((noinline)) void +foo (int *x) +{ + int i; + int curr_a, flag, next_a; + + curr_a = a[0]; + + for (i = 0; i < N; i++) + { + flag = *x > c[i]; + next_a = a[i+1]; + curr_a = flag ? curr_a : next_a; + } + + *x = curr_a; +} + +int main (void) +{ + int x = 7; + + check_vect (); + + foo (&x); + + if (x != 256) + abort (); + + return 0; +} + +/* The order of computation should not be changed for cond_expr, therefore, + it cannot be vectorized in reduction. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-3.c b/gcc/testsuite/gcc.dg/vect/vect-cond-3.c new file mode 100644 index 000000000..32ebf0fff --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-3.c @@ -0,0 +1,65 @@ +/* { dg-require-effective-target vect_condition } */ + +#include <stdlib.h> +#include "tree-vect.h" + +#define M 32 +#define N 16 + +int x_in[M]; +int x_out_a[M], x_out_b[M]; +int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2}; +int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024}; +int b[N+1] = {17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; +int check_result_a[M] = {1024,1024,1024,256,256,256,256,256,256,256,256,128,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48}; +int check_result_b[M] = {17,17,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + +__attribute__ ((noinline)) void +foo () +{ + int j, i, x; + int curr_a, flag, next_a, curr_b, next_b; + + for (j = 0; j < M; j++) + { + x = x_in[j]; + curr_a = a[0]; + curr_b = b[0]; + + for (i = 0; i < N; i++) + { + flag = x > c[i]; + next_a = a[i+1]; + next_b = b[i+1]; + curr_a = flag ? curr_a : next_a; + curr_b = flag ? next_b : curr_b; + } + + x_out_a[j] = curr_a; + x_out_b[j] = curr_b; + } +} + +int main (void) +{ + int i,j; + + check_vect (); + + for (j = 0; j < M; j++) + x_in[j] = j; + + foo (); + + for (j = 0; j < M; j++) + if (x_out_a[j] != check_result_a[j] + || x_out_b[j] != check_result_b[j]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-4.c b/gcc/testsuite/gcc.dg/vect/vect-cond-4.c new file mode 100644 index 000000000..3c37c6825 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-4.c @@ -0,0 +1,62 @@ +/* { dg-require-effective-target vect_condition } */ + +#include <stdlib.h> +#include "tree-vect.h" + +#define M 32 +#define N 16 + +int x_in[M]; +int x_out_a[M], x_out_b[M]; +int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2}; +int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024}; +int b[N+1] = {17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; +int check_result_a[M] = {1024,1024,1024,256,256,256,256,256,256,256,256,128,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48}; +int check_result_b[M] = {17,17,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; + +__attribute__ ((noinline)) void +foo (int z) +{ + int j, i, x; + int curr_a, curr_b; + + for (j = 0; j < M; j++) + { + x = x_in[j]; + curr_a = a[0]; + curr_b = b[0]; + + for (i = 0; i < N; i++) + { + curr_a = x > c[i] ? curr_a : z; + curr_b = x > c[i] ? curr_b : 5; + } + + x_out_a[j] = curr_a; + x_out_b[j] = curr_b; + } +} + +int main (void) +{ + int i,j; + + check_vect (); + + for (j = 0; j < M; j++) + x_in[j] = j; + + foo (125); + + for (j = 0; j < M; j++) + if (x_out_a[j] != 125 + || x_out_b[j] != 5) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-5.c b/gcc/testsuite/gcc.dg/vect/vect-cond-5.c new file mode 100644 index 000000000..8d28a45ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-5.c @@ -0,0 +1,61 @@ +/* { dg-require-effective-target vect_condition } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +int cond_array[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int a[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; +int check_result[K] = {2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +__attribute__ ((noinline)) void +foo (int c) +{ + int res, i, j, k, next; + + for (k = 0; k < K; k++) + { + res = 0; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + { + next = a[i][j]; + res = c > cond_array[i+k][j] ? next : res; + } + + out[k] = res; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + cond_array[i][j] = i+j; + + for (i = 0; i < K; i++) + a[i][j] = i+2; + } + + foo(5); + + for (k = 0; k < K; k++) + if (out[k] != check_result[k]) + abort (); + + return 0; +} + +/* Double reduction with cond_expr is not supported, since eventhough the order + of computation is the same, but vector results should be reduced to scalar + result, which can'be done for cond_expr. */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-6.c b/gcc/testsuite/gcc.dg/vect/vect-cond-6.c new file mode 100644 index 000000000..944c9c272 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-cond-6.c @@ -0,0 +1,59 @@ +/* { dg-require-effective-target vect_condition } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +int cond_array[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int a[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; + +__attribute__ ((noinline)) void +foo (int c) +{ + int res, i, j, k, next; + + for (k = 0; k < K; k++) + { + for (j = 0; j < K; j++) + { + res = 0; + for (i = 0; i < K; i++) + { + next = a[i][j]; + res = c > cond_array[i+k][j] ? next : res; + } + + out[j] = res; + } + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + cond_array[i][j] = i+j; + + for (i = 0; i < K; i++) + a[i][j] = i+2; + } + + foo(125); + + for (k = 0; k < K; k++) + if (out[k] != 33) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-debug-pr41926.c b/gcc/testsuite/gcc.dg/vect/vect-debug-pr41926.c new file mode 100644 index 000000000..a2d36d3b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-debug-pr41926.c @@ -0,0 +1,21 @@ +/* PR debug/41926 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -ffast-math -funroll-loops -ftree-vectorize -msse2" { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-require-effective-target sse2 { target { i?86-*-* x86_64-*-* } } } */ + +void +foo (double (*__restrict p)[4], double (*__restrict q)[4], + double *__restrict prim, double scale, double pp, double pq) +{ + int md, mc, mb, ma, p_index = 0; + + for (md = 0; md < 1; md++) + for (mc = 0; mc < 1; mc++) + for (mb = 0; mb < 1; mb++) + for (ma = 0; ma < 4; ma++) + { + double tmp = scale * prim[p_index++]; + p[md][ma] = p[md][ma] - tmp * pp; + q[mc][ma] = q[mc][ma] - tmp * pq; + } +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-double-reduc-1.c b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-1.c new file mode 100644 index 000000000..7dd6b494d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-1.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; +int check_result[K] = {642816,660736,678656,696576,714496,732416,750336,768256,786176,804096,822016,839936,857856,875776,893696,911616,929536,947456,965376,983296,1001216,1019136,1037056,1054976,1072896,1090816,1108736,1126656,1144576,1162496,1180416,1198336}; + +__attribute__ ((noinline)) void +foo () +{ + int sum = 0, i, j, k; + + for (k = 0; k < K; k++) + { + sum = 0; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + sum += in[i+k][j] * coeff[i][j]; + + out[k] = sum; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + in[i][j] = i+j; + + for (i = 0; i < K; i++) + coeff[i][j] = i+2; + } + + foo(); + + for (k = 0; k < K; k++) + if (out[k] != check_result[k]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-double-reduc-2.c b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-2.c new file mode 100644 index 000000000..50d014174 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-2.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; +int check_result[K] = {357184,339264,321344,303424,285504,267584,249664,231744,213824,195904,177984,160064,142144,124224,106304,88384,70464,52544,34624,16704,-1216,-19136,-37056,-54976,-72896,-90816,-108736,-126656,-144576,-162496,-180416,-198336}; + +__attribute__ ((noinline)) void +foo () +{ + int res = 0, i, j, k; + + for (k = 0; k < K; k++) + { + res = 1000000; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + res -= in[i+k][j] * coeff[i][j]; + + out[k] = res; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + in[i][j] = i+j; + + for (i = 0; i < K; i++) + coeff[i][j] = i+2; + } + + foo(); + + for (k = 0; k < K; k++) + if (out[k] != check_result[k]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-double-reduc-3.c b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-3.c new file mode 100644 index 000000000..f5376b8bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-3.c @@ -0,0 +1,66 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out_max[K], out_min[K]; +int check_max[K] = {62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93}; +int check_min[K] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + +__attribute__ ((noinline)) void +foo (int x, int y) +{ + int max, min, i, j, k; + + for (k = 0; k < K; k++) + { + max = x; + min = y; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + { + max = max < in[i+k][j] ? in[i+k][j] : max; + min = min > in[i+k][j] ? in[i+k][j] : min; + } + out_max[k] = max; + out_min[k] = min; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + in[i][j] = i+j; + + for (i = 0; i < K; i++) + coeff[i][j] = i+2; + } + + foo(0, 0); + + for (k = 0; k < K; k++) + if (out_max[k] != check_max[k] || out_min[k] != 0) + abort (); + + foo(100, 45); + + for (k = 0; k < K; k++) + if (out_min[k] != check_min[k] || out_max[k] != 100) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-double-reduc-4.c b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-4.c new file mode 100644 index 000000000..7ab6b69ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-4.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; +int check_result[K] = {652816,670736,688656,706576,724496,742416,760336,778256,796176,814096,832016,849936,867856,885776,903696,921616,939536,957456,975376,993296,1011216,1029136,1047056,1064976,1082896,1100816,1118736,1136656,1154576,1172496,1190416,1208336}; + +__attribute__ ((noinline)) void +foo () +{ + int sum = 0, i, j, k; + + for (k = 0; k < K; k++) + { + sum = 10000; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + sum += in[i+k][j] * coeff[i][j]; + + out[k] = sum; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + in[i][j] = i+j; + + for (i = 0; i < K; i++) + coeff[i][j] = i+2; + } + + foo(); + + for (k = 0; k < K; k++) + if (out[k] != check_result[k]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-double-reduc-5.c b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-5.c new file mode 100644 index 000000000..48457628f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-5.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +signed short in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; +int check_result[K] = {642816,660736,678656,696576,714496,732416,750336,768256,786176,804096,822016,839936,857856,875776,893696,911616,929536,947456,965376,983296,1001216,1019136,1037056,1054976,1072896,1090816,1108736,1126656,1144576,1162496,1180416,1198336}; + +__attribute__ ((noinline)) void +foo () +{ + int sum = 0, i, j, k; + + for (k = 0; k < K; k++) + { + sum = 0; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + sum += in[i+k][j] * coeff[i][j]; + + out[k] = sum; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + in[i][j] = i+j; + + for (i = 0; i < K; i++) + coeff[i][j] = i+2; + } + + foo(); + + for (k = 0; k < K; k++) + if (out[k] != check_result[k]) + abort (); + + return 0; +} + +/* Vectorization of loops with multiple types and double reduction is not + supported yet. */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-double-reduc-6.c b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-6.c new file mode 100644 index 000000000..6b14e3bf5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-6.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int_mult } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 4 + +int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; +int check_result[K] = {0,16,256,4096}; + +__attribute__ ((noinline)) void +foo () +{ + int sum; + int i, j, k; + + for (k = 0; k < K; k++) + { + sum = 1; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + sum *= in[i+k][j]; + out[k] = sum; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (i = 0; i < 2*K; i++) + for (j = 0; j < K; j++) + in[i][j] = (i+2)/3; + + foo(); + + for (k = 0; k < K; k++) + if (out[k] != check_result[k]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-double-reduc-7.c b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-7.c new file mode 100644 index 000000000..34a6f600e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-double-reduc-7.c @@ -0,0 +1,64 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define K 32 + +int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int out[K]; +int check_result[K] = {63,63,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191}; + +__attribute__ ((noinline)) void +foo () +{ + int res_or, res_and, res_xor, i, j, k; + + for (k = 0; k < K; k++) + { + res_or = 0; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + res_or = res_or | in[i+k][j]; + + res_and = 1; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + res_and = res_and & in[i+k][j]; + + res_xor = 0; + for (j = 0; j < K; j++) + for (i = 0; i < K; i++) + res_xor = res_xor ^ in[i+k][j]; + + out[k] = res_or + res_and + res_xor; + } +} + +int main () +{ + int i, j, k; + + check_vect (); + + for (j = 0; j < K; j++) + { + for (i = 0; i < 2*K; i++) + in[i][j] = i+j; + + for (i = 0; i < K; i++) + out[i] = i+j; + } + + foo(); + + for (k = 0; k < K; k++) + if (out[k] != check_result[k]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 3 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-dv-1.c b/gcc/testsuite/gcc.dg/vect/vect-dv-1.c new file mode 100644 index 000000000..0da4cd978 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-dv-1.c @@ -0,0 +1,22 @@ +/* Test compiler crash when dependence analyzer can not represent + dependence relation by distance vector. */ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +int x[199]; + +void foo() + +{ + int t,j; + + for (j=99;j>0;j--) + x [j+j]=x[j]; + + for (j=198;j>=100;j--) + if(x[j]) + { + x[j-63]=x[j-3]-x[j]; + } +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c b/gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c new file mode 100644 index 000000000..3035ee392 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-float-extend-1.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +float fb[N] = {0.4,3.5,6.6,9.4,12.5,15.6,18.4,21.5,24.6,27.4,30.5,33.6,36.4,39.5,42.6,45.4,0.5,3.6,6.4,9.5,12.6,15.4,18.5,21.6,24.4,27.5,30.6,33.4,36.5,39.6,42.4,45.5}; +double da[N]; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + + /* float -> double */ + for (i = 0; i < N; i++) + { + da[i] = (double) fb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (da[i] != (double) fb[i]) + abort (); + } + + return 0; +} + +int +main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail spu*-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c b/gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c new file mode 100644 index 000000000..b7a9b47bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-float-truncate-1.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +__attribute__ ((noinline)) int +main1 () +{ + int i; + double db[N] = {0.4,3.5,6.6,9.4,12.5,15.6,18.4,21.5,24.6,27.4,30.5,33.6,36.4,39.5,42.6,45.4,0.5,3.6,6.4,9.5,12.6,15.4,18.5,21.6,24.4,27.5,30.6,33.4,36.5,39.6,42.4,45.5}; + float fa[N]; + + /* double -> float */ + for (i = 0; i < N; i++) + { + fa[i] = (float) db[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (fa[i] != (float) db[i]) + abort (); + } + + return 0; +} + +int +main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail spu*-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-floatint-conversion-1.c b/gcc/testsuite/gcc.dg/vect/vect-floatint-conversion-1.c new file mode 100644 index 000000000..e5b72f1ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-floatint-conversion-1.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +float fb[N] = {0.4,3.5,6.6,9.4,12.5,15.6,18.4,21.5,24.6,27.4,30.5,33.6,36.4,39.5,42.6,45.4,0.5,3.6,6.4,9.5,12.6,15.4,18.5,21.6,24.4,27.5,30.6,33.4,36.5,39.6,42.4,45.5}; +int ia[N]; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + + /* float -> int */ + for (i = 0; i < N; i++) + { + ia[i] = (int) fb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != (int) fb[i]) + abort (); + } + + return 0; +} + +int +main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_floatint_cvt } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-floatint-conversion-2.c b/gcc/testsuite/gcc.dg/vect/vect-floatint-conversion-2.c new file mode 100644 index 000000000..683b43c51 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-floatint-conversion-2.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +__attribute__ ((noinline)) int +main1 () +{ + int i; + double db[N] = {0.4,3.5,6.6,9.4,12.5,15.6,18.4,21.5,24.6,27.4,30.5,33.6,36.4,39.5,42.6,45.4,0.5,3.6,6.4,9.5,12.6,15.4,18.5,21.6,24.4,27.5,30.6,33.4,36.5,39.6,42.4,45.5}; + int ia[N]; + + /* double -> int */ + for (i = 0; i < N; i++) + { + ia[i] = (int) db[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != (int) db[i]) + abort (); + } + + return 0; +} + +int +main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_floatint_cvt } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-fold-1.c b/gcc/testsuite/gcc.dg/vect/vect-fold-1.c new file mode 100644 index 000000000..8aca1e420 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-fold-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ccp1" } */ + +typedef unsigned char v4qi __attribute__ ((vector_size (4))); + +v4qi c; + +void foo() +{ + v4qi a = { 1, 2, 3, 4 }; + v4qi b = { 5, 6, 7, 8 }; + c = a + b; +} + +/* { dg-final { scan-tree-dump-times "c =.* { 6, 8, 10, 12 }" 1 "ccp1" } } */ +/* { dg-final { cleanup-tree-dump "ccp1" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-10.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-10.c new file mode 100644 index 000000000..8a4b24ed4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-10.c @@ -0,0 +1,12 @@ +/* PR 21272 */ +/* { dg-do compile } */ +double +foo (int j, double *v, double x) +{ + int i; + for (i = 0; i < j; i++) + if (v[i] < x) + x = v[i]; + return x; +} +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c new file mode 100644 index 000000000..8071c87d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-16.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +extern void abort(void); + +float A[N] = {36,39,42,45,43,32,21,42,23,34,45,56,67,42,89,11}; +float B[N] = {42,42,0,42,42,42,42,0,42,42,42,42,42,0,42,42}; + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] != MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c new file mode 100644 index 000000000..a02c8984e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-17.c @@ -0,0 +1,34 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +float A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,42,78,89,11}; +float B[N] = {42,42,0,42,42,42,42,42,42,42,42,42,0,42,42,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] == MAX ? 0 : MAX); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-2.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-2.c new file mode 100644 index 000000000..e899f126d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-2.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] >= MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-3.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-3.c new file mode 100644 index 000000000..1d8e9f52b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-3.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +int B[N] = {0,0,0,42,42,0,0,0,0,0,42,42,42,42,42,0}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] > MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-4.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-4.c new file mode 100644 index 000000000..1680cba8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-4.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +int B[N] = {42,42,42,0,0,42,42,42,42,42,0,0,0,0,0,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] <= MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-5.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-5.c new file mode 100644 index 000000000..5fc9674b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-5.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +int B[N] = {42,42,0,0,0,42,42,42,42,42,0,0,0,0,0,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] < MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-6.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-6.c new file mode 100644 index 000000000..24e8c969e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-6.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +int A[N] = {36,39,42,45,43,32,21,42,23,34,45,56,67,42,89,11}; +int B[N] = {42,42,0,42,42,42,42,0,42,42,42,42,42,0,42,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] != MAX ? MAX : 0); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-7.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-7.c new file mode 100644 index 000000000..fa4cf3a58 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-7.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,42,78,89,11}; +int B[N] = {42,42,0,42,42,42,42,42,42,42,42,42,0,42,42,42}; + +extern void abort(void); + +int main () +{ + int i, j; + + check_vect (); + + for (i = 0; i < 16; i++) + A[i] = ( A[i] == MAX ? 0 : MAX); + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-ifcvt-9.c b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-9.c new file mode 100644 index 000000000..50eedb1d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-ifcvt-9.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_condition } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 16 +#define MAX 42 + +extern void abort(void); + +int A[N] = {36,39,42,45,43,32,21,12,23,34,45,56,67,78,89,11}; +int B[N] = {0,0,42,42,42,0,0,0,0,0,42,42,42,42,42,0}; +inline void foo () __attribute__((always_inline)); +void foo () +{ + int i, j; + + for (i = 0; i < 16; i++) + A[i] = ( A[i] >= MAX ? MAX : 0); +} + +int main () +{ + + int i, j; + check_vect (); + foo (); + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-1.c b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-1.c new file mode 100644 index 000000000..90f33a508 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-1.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +float fa[N]; + +__attribute__ ((noinline)) int main1 () +{ + int i; + + /* int -> float */ + for (i = 0; i < N; i++) + { + fa[i] = (float) ib[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (fa[i] != (float) ib[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_intfloat_cvt } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-2.c b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-2.c new file mode 100644 index 000000000..87f200119 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-2.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +int int_arr[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +float float_arr[N]; +char char_arr[N]; + +__attribute__ ((noinline)) int main1 () +{ + int i; + + for (i = 0; i < N; i++){ + float_arr[i] = (float) int_arr[i]; + char_arr[i] = 0; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (float_arr[i] != (float) int_arr[i]) + abort (); + if (char_arr[i] != 0) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_intfloat_cvt } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-3.c b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-3.c new file mode 100644 index 000000000..d5f25df71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-3.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_double } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +double da[N]; + +__attribute__ ((noinline)) int main1 () +{ + int i; + + /* int -> double */ + for (i = 0; i < N; i++) + { + da[i] = (double) ib[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (da[i] != (double) ib[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_intfloat_cvt } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-4a.c b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-4a.c new file mode 100644 index 000000000..af8344ba6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-4a.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,-3,-6,-9,-12,-15,-18,-21,-24,-27,-30,-33,-36,-39,-42,-45}; +float fa[N]; + +__attribute__ ((noinline)) int main1 () +{ + int i; + + /* short -> float */ + for (i = 0; i < N; i++) + { + fa[i] = (float) sb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (fa[i] != (float) sb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_intfloat_cvt } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-4b.c b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-4b.c new file mode 100644 index 000000000..51ea056fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-intfloat-conversion-4b.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +unsigned short usb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,65533,65530,65527,65524,65521,65518,65515,65512,65509,65506,65503,65500,65497,65494,65491}; +float fa[N]; + +__attribute__ ((noinline)) int main1 () +{ + int i; + + /* unsigned short -> float */ + for (i = 0; i < N; i++) + { + fa[i] = (float) usb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (fa[i] != (float) usb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_intfloat_cvt } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-1.c b/gcc/testsuite/gcc.dg/vect/vect-iv-1.c new file mode 100644 index 000000000..5d6ab5cd2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-1.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +int result[N] = {8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38}; + +__attribute__ ((noinline)) int main1 (int X) +{ + int arr[N]; + int k = X; + int m, i=0; + + /* vectorization of induction. */ + + do { + m = k + 5; + arr[i] = m; + k = k + 2; + i++; + } while (i < N); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr[i] != result[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (3); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-10.c b/gcc/testsuite/gcc.dg/vect/vect-iv-10.c new file mode 100644 index 000000000..7ec487253 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-10.c @@ -0,0 +1,36 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) +int main1 () +{ + int i,j; + int ia[N]; + + /* Induction. */ + for (j=0,i=N; j<N,i>0; i--,j++) { + ia[j] = i; + } + + /* check results: */ + for (j=0,i=N; j<N,i>0; i--,j++) { + if (ia[j] != i) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect(); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-11.c b/gcc/testsuite/gcc.dg/vect/vect-iv-11.c new file mode 100644 index 000000000..ef1c57744 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-11.c @@ -0,0 +1,31 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +int main1 (int len) +{ + int s = 0; + int i = len; + + /* vectorization of induction with reduction. */ + for ( ; i > 1; i -=2) + s += i; + + return s; +} + +int main (void) +{ + int s; + check_vect (); + + s = main1 (26); + if (s != 182) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-2.c b/gcc/testsuite/gcc.dg/vect/vect-iv-2.c new file mode 100644 index 000000000..df34a99c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-2.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) int main1 () +{ + int arr1[N]; + int k = 0; + int m = 3, i = 0; + + /* Vectorization of induction that is used after the loop. + Currently vectorizable because scev_ccp disconnects the + use-after-the-loop from the iv def inside the loop. */ + + do { + k = k + 2; + arr1[i] = k; + m = m + k; + i++; + } while (i < N); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr1[i] != 2+2*i) + abort (); + } + + return m + k; +} + +int main (void) +{ + int res; + + check_vect (); + + res = main1 (); + if (res != 32 + 275) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-3.c b/gcc/testsuite/gcc.dg/vect/vect-iv-3.c new file mode 100644 index 000000000..fac303a67 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-3.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) int main1 () +{ + int arr1[N]; + int arr2[N]; + int k = 0; + int m = 3, i = 0; + + /* vectorization of induction. + Peeling to align the store is also applied. */ + + do { + k = k + 2; + arr1[i] = k; + m = k + 3; + arr2[i] = m; + i++; + } while (i < N); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr1[i] != 2+2*i || arr2[i] != 5 + 2*i) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-4.c b/gcc/testsuite/gcc.dg/vect/vect-iv-4.c new file mode 100644 index 000000000..fe29cff18 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-4.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) int main1 () +{ + unsigned int arr1[N]; + unsigned short arr2[N]; + unsigned int k = 0; + unsigned short m = 3; + int i = 0; + + /* Vectorization of induction with multiple data types. */ + + do { + k = k + 2; + arr1[i] = k; + m = k + 3; + arr2[i] = m; + i++; + } while (i < N); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr1[i] != 2+2*i || arr2[i] != 5 + 2*i) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-5.c b/gcc/testsuite/gcc.dg/vect/vect-iv-5.c new file mode 100644 index 000000000..1766ae6a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-5.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) int main1 () +{ + float arr[N]; + float f = 1.0; + int i; + + /* Vectorization of fp induction. */ + + for (i=0; i<N; i++) + { + arr[i] = f; + f += 2.0; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr[i] != 1.0 + 2.0*i) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-6.c b/gcc/testsuite/gcc.dg/vect/vect-iv-6.c new file mode 100644 index 000000000..96d3fbf52 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-6.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int_mult } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +__attribute__ ((noinline)) int main1 (int X) +{ + int arr1[N+1]; + int arr2[N+1]; + int k = X; + int m, i=0; + + /* Vectorization of induction with non-constant initial condition X. + Also we have here two uses of the induction-variable k as defined + by the loop-header phi (as opposed to the other uses of k that are + defined in the loop), in which case we exercise the fact that we + reuse the same vector def-use-cycle for both uses. + Peeling to align the store is also applied. This peeling also aligns + the load (as they have the same misalignment). */ + + do { + arr2[i+1] = 2*k; + k = k + 2; + arr1[i+1] = k; + k = k + 4; + i++; + } while (i < N); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr1[i+1] != X+6*i+2 + || arr2[i+1] != 2*(X+6*i)) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (3); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-7.c b/gcc/testsuite/gcc.dg/vect/vect-iv-7.c new file mode 100644 index 000000000..140d903a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-7.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +int result[N] = {8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38}; + +__attribute__ ((noinline)) int main1 (int X) +{ + int arr[N]; + int k = 3; + int m, i=0; + + /* Vectorization of induction with non-constant step X. */ + + do { + m = k + 5; + arr[i] = m; + k = k + X; + i++; + } while (i < N); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (arr[i] != result[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (2); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-8.c b/gcc/testsuite/gcc.dg/vect/vect-iv-8.c new file mode 100644 index 000000000..6544988b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-8.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 26 + +__attribute__ ((noinline)) int main1 (short X) +{ + unsigned char a[N]; + unsigned short b[N]; + unsigned int c[N]; + short myX = X; + int i; + + /* vectorization of induction with type conversions. */ + for (i = 0; i < N; i++) + { + a[i] = (unsigned char)X; + b[i] = X; + c[i] = (unsigned int)X; + X++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (a[i] != (unsigned char)myX || b[i] != myX || c[i] != (unsigned int)myX++) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (3); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_pack_trunc && vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-8a.c b/gcc/testsuite/gcc.dg/vect/vect-iv-8a.c new file mode 100644 index 000000000..dc742eb84 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-8a.c @@ -0,0 +1,43 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 26 + +__attribute__ ((noinline)) int main1 (short X) +{ + signed char a[N]; + short b[N]; + int c[N]; + short myX = X; + int i; + + /* vectorization of induction with type conversions. */ + for (i = 0; i < N; i++) + { + a[i] = (signed char)X; + b[i] = X; + c[i] = (int)X; + X++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (a[i] != (signed char)myX || b[i] != myX || c[i] != (int)myX++) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (3); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_pack_trunc && vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-9.c b/gcc/testsuite/gcc.dg/vect/vect-iv-9.c new file mode 100644 index 000000000..28ce927bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-9.c @@ -0,0 +1,38 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 26 +int a[N]; + +__attribute__ ((noinline)) int main1 (int X) +{ + int s = X; + int i; + + /* vectorization of reduction with induction. */ + for (i = 0; i < N; i++) + s += (i + a[i]); + + return s; +} + +int main (void) +{ + int s, i; + check_vect (); + + for (i = 0; i < N; i++) + a[i] = 2*i; + + s = main1 (3); + if (s != 978) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_int_mult } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target {! vect_int_mult } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c new file mode 100644 index 000000000..5e2b41a82 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c @@ -0,0 +1,88 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +short sa[N]; +short sb[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +int ia[N]; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Current peeling-for-alignment scheme will consider the 'sa[i+7]' + access for peeling, and therefore will examine the option of + using a peeling factor = V-7%V = 1,3 for V=8,4 respectively, + which will also align the access to 'ia[i+3]', and the loop could be + vectorized on all targets that support unaligned loads. */ + +__attribute__ ((noinline)) int main1 (int n) +{ + int i; + + /* Multiple types with different sizes, used in idependent + copmutations. Vectorizable. */ + for (i = 0; i < n; i++) + { + sa[i+7] = sb[i]; + ia[i+3] = ib[i+1]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (sa[i+7] != sb[i] || ia[i+3] != ib[i+1]) + abort (); + } + + return 0; +} + +/* Current peeling-for-alignment scheme will consider the 'ia[i+3]' + access for peeling, and therefore will examine the option of + using a peeling factor = (V-3)%V = 1 for V=2,4. + This will not align the access 'sa[i+3]' (for which we need to + peel 5 iterations). However, 'ia[i+3]' also gets aligned if we peel 5 + iterations, so the loop is vectorizable on all targets that support + unaligned loads. */ + +__attribute__ ((noinline)) int main2 (int n) +{ + int i; + + /* Multiple types with different sizes, used in independent + copmutations. */ + for (i = 0; i < n; i++) + { + ia[i+3] = ib[i]; + sa[i+3] = sb[i+1]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (sa[i+3] != sb[i+1] || ia[i+3] != ib[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N-7); + main2 (N-3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-10.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-10.c new file mode 100644 index 000000000..60a4fc854 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-10.c @@ -0,0 +1,68 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char uX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short uY[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned int uresult[N]; +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int result[N]; + +/* Unsigned type promotion (hi->si) */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + uX[i] = 5; + uresult[i] = (unsigned int)uY[i]; + } +} + +/* Signed type promotion (hi->si) */ +__attribute__ ((noinline)) int +foo2(int len) { + int i; + + for (i=0; i<len; i++) { + uX[i] = 5; + result[i] = (int)Y[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = 16-i; + uX[i] = 16-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (uresult[i] != (unsigned short)uY[i]) + abort (); + } + + foo2 (N); + + for (i=0; i<N; i++) { + if (result[i] != (short)Y[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-11.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-11.c new file mode 100644 index 000000000..9cb8c1dfe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-11.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +short x[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) int +foo (int len, int *z) { + int i; + + for (i=0; i<len; i++) { + z[i] = x[i]; + } +} + + +int main (void) +{ + short i; + int z[N+4]; + + check_vect (); + + for (i=0; i<N; i++) { + x[i] = i; + } + + foo (N,z+2); + + for (i=0; i<N; i++) { + if (z[i+2] != x[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-12.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-12.c new file mode 100644 index 000000000..977c33255 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-12.c @@ -0,0 +1,44 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +char x[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) int +foo (int len, int *z) { + int i; + + for (i=0; i<len; i++) { + z[i] = x[i]; + } +} + + +int main (void) +{ + char i; + int z[N+4]; + + check_vect (); + + for (i=0; i<N; i++) { + x[i] = i; + } + + foo (N,z+2); + + for (i=0; i<N; i++) { + if (z[i+2] != x[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ +/* { dg-final { if [ istarget sparc*-*-* ] { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail ilp32 } } else { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect_unpack } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-13.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-13.c new file mode 100644 index 000000000..4200e62a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-13.c @@ -0,0 +1,64 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char uX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned int uresult[N]; +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int result[N]; + +/* Unsigned type promotion (qi->si) */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + uresult[i] = (unsigned int)uX[i]; + } +} + +/* Signed type promotion (qi->si) */ +__attribute__ ((noinline)) int +foo2(int len) { + int i; + + for (i=0; i<len; i++) { + result[i] = (int)X[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = 16-i; + uX[i] = 16-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (uresult[i] != (unsigned int)uX[i]) + abort (); + } + + foo2 (N); + + for (i=0; i<N; i++) { + if (result[i] != (int)X[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-14.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-14.c new file mode 100644 index 000000000..816f4e49c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-14.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char uX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned char uresultX[N]; +unsigned int uY[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned char uresultY[N]; + +/* Unsigned type demotion (si->qi) */ + +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + uresultX[i] = uX[i]; + uresultY[i] = (unsigned char)uY[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + uX[i] = 16-i; + uY[i] = 16-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (uresultX[i] != uX[i]) + abort (); + if (uresultY[i] != (unsigned char)uY[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-15.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-15.c new file mode 100644 index 000000000..145bb5d7e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-15.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT1 43680 +#define DOT2 -20832 + +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned char CX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo1(int len) { + int i; + int result1 = 0; + + for (i=0; i<len; i++) { + result1 += (X[i] * Y[i]); + CX[i] = 5; + } + + if (result1 != DOT1) + abort (); +} + + +int main (void) +{ + int i, dot1, dot2; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + CX[i] = i; + __asm__ volatile (""); + } + + foo1 (N); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_sdot_hi || vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-16.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-16.c new file mode 100644 index 000000000..176333c2b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-16.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_long_long } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +char x[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + +__attribute__ ((noinline)) int +foo (int len, long long *z) { + int i; + + for (i=0; i<len; i++) { + z[i] = x[i]; + } +} + + +int main (void) +{ + char i; + long long z[N+4]; + + check_vect (); + + foo (N,z+2); + + for (i=0; i<N; i++) { + if (z[i+2] != x[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-17.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-17.c new file mode 100644 index 000000000..b2f810582 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-17.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_long_long } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char uX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; +unsigned char uresultX[N]; +unsigned long long uY[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; +unsigned char uresultY[N]; + +/* Unsigned type demotion (si->qi) */ + +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + uresultX[i] = uX[i]; + uresultY[i] = (unsigned char)uY[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + foo1 (N); + + for (i=0; i<N; i++) { + if (uresultX[i] != uX[i]) + abort (); + if (uresultY[i] != (unsigned char)uY[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-2.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-2.c new file mode 100644 index 000000000..4ae47f2c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-2.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +int ia[N]; +int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +short sa[N]; +short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +char ca[N]; +char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) int main1 () +{ + int i; + + /* Multiple types with different sizes, used in independent + cmputations. Vectorizable. All accesses aligned. */ + for (i = 0; i < N; i++) + { + ia[i] = ib[i]; + sa[i] = sb[i]; + ca[i] = cb[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i] + || sa[i] != sb[i] + || ca[i] != cb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c new file mode 100644 index 000000000..3346e71e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-3.c @@ -0,0 +1,59 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +int ib[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +short sb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +char cb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 (int n, int * __restrict__ pib, + short * __restrict__ psb, + char * __restrict__ pcb) +{ + int i; + int ia[N]; + short sa[N]; + char ca[N]; + + /* Multiple types with different sizes, used in independent + computations. Vectorizable. The loads are misaligned. */ + for (i = 0; i < n; i++) + { + ia[i] = pib[i]; + sa[i] = psb[i]; + ca[i] = pcb[i]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (ia[i] != pib[i] + || sa[i] != psb[i] + || ca[i] != pcb[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N, ib, sb, cb); + main1 (N-3, ib, sb, &cb[2]); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {xfail { vect_no_align } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c new file mode 100644 index 000000000..9cb6817ce --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c @@ -0,0 +1,101 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +unsigned short sa[N]; +unsigned short sc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +unsigned short sb[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, + 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; +unsigned int ia[N]; +unsigned int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; +unsigned int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Current peeling-for-alignment scheme will consider the 'sa[i+7]' + access for peeling, and therefore will examine the option of + using a peeling factor = VF-7%VF. This will result in a peeling factor 1, + which will also align the access to 'ia[i+3]', and the loop could be + vectorized on all targets that support unaligned loads. + Without cost model on targets that support misaligned stores, no peeling + will be applied since we want to keep the four loads aligned. */ + +__attribute__ ((noinline)) +int main1 (int n) +{ + int i; + + /* Multiple types with different sizes, used in independent + copmutations. Vectorizable. */ + for (i = 0; i < n; i++) + { + sa[i+7] = sb[i] + sc[i]; + ia[i+3] = ib[i] + ic[i]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (sa[i+7] != sb[i] + sc[i] || ia[i+3] != ib[i] + ic[i]) + abort (); + } + + return 0; +} + +/* Current peeling-for-alignment scheme will consider the 'ia[i+3]' + access for peeling, and therefore will examine the option of + using a peeling factor = VF-3%VF. This will result in a peeling factor + 1 if VF=4,2. This will not align the access to 'sa[i+3]', for which we + need to peel 5,1 iterations for VF=4,2 respectively, so the loop can not + be vectorized. However, 'ia[i+3]' also gets aligned if we peel 5 + iterations, so the loop is vectorizable on all targets that support + unaligned loads. + Without cost model on targets that support misaligned stores, no peeling + will be applied since we want to keep the four loads aligned. */ + +__attribute__ ((noinline)) +int main2 (int n) +{ + int i; + + /* Multiple types with different sizes, used in independent + copmutations. Vectorizable. */ + for (i = 0; i < n; i++) + { + ia[i+3] = ib[i] + ic[i]; + sa[i+3] = sb[i] + sc[i]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (sa[i+3] != sb[i] + sc[i] || ia[i+3] != ib[i] + ic[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N-7); + main2 (N-3); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail { vect_no_align } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" { target { vect_element_align} } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align || vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 8 "vect" { xfail { vect_no_align || vect_element_align } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { target { vect_element_align } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-5.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-5.c new file mode 100644 index 000000000..30ec68406 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-5.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +unsigned int ia[N]; +unsigned int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned short sa[N]; +unsigned short sc[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char ca[N]; +unsigned char cc[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + + /* Multiple types with different sizes, used in independent + computations. Vectorizable. All accesses aligned. */ + for (i = 0; i < N; i++) + { + ia[i] = ib[i] + ic[i]; + sa[i] = sb[i] + sc[i]; + ca[i] = cb[i] + cc[i]; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (ia[i] != ib[i] + ic[i] + || sa[i] != sb[i] + sc[i] + || ca[i] != cb[i] + cc[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { sparc*-*-* && ilp32 } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c new file mode 100644 index 000000000..5bb4be8c3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-6.c @@ -0,0 +1,66 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +unsigned int ic[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int ib[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned short sc[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned short sb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char cc[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char cb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = + {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + +__attribute__ ((noinline)) +int main1 (int n, + unsigned int * __restrict__ pic, unsigned int * __restrict__ pib, + unsigned short * __restrict__ psc, unsigned short * __restrict__ psb, + unsigned char * __restrict__ pcc, unsigned char * __restrict__ pcb) +{ + int i; + unsigned int ia[N]; + unsigned short sa[N]; + unsigned char ca[N]; + + /* Multiple types with different sizes, used in independent + computations. Vectorizable. The loads are misaligned. */ + for (i = 0; i < n; i++) + { + ia[i] = pib[i] + pic[i]; + sa[i] = psb[i] + psc[i]; + ca[i] = pcb[i] + pcc[i]; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (ia[i] != pib[i] + pic[i] + || sa[i] != psb[i] + psc[i] + || ca[i] != pcb[i] + pcc[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N, ic, ib, sc, sb, cc, cb); + main1 (N-3, ic, ib, &sc[1], sb, cc, &cb[2]); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { sparc*-*-* && ilp32 } }} } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 6 "vect" {xfail { vect_no_align } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-7.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-7.c new file mode 100644 index 000000000..ae6ee1a06 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-7.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT1 43680 +#define DOT2 -20832 + +signed short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned char CX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo1(int len) { + int i; + int result1 = 0; + short prod; + + for (i=0; i<len; i++) { + result1 += (X[i] * Y[i]); + CX[i] = 5; + } + + if (result1 != DOT1) + abort (); +} + + +int main (void) +{ + int i, dot1, dot2; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + CX[i] = i; + __asm__ volatile (""); + } + + foo1 (N); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_sdot_hi } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-8.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-8.c new file mode 100644 index 000000000..699c87bd1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-8.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char uX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned char uresultX[N]; +unsigned int uY[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short uresultY[N]; + +/* Unsigned type demotion (si->hi) */ + +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + uresultX[i] = uX[i]; + uresultY[i] = (unsigned short)uY[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + uX[i] = 16-i; + uY[i] = 16-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (uresultX[i] != uX[i]) + abort (); + if (uresultY[i] != (unsigned short)uY[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-9.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-9.c new file mode 100644 index 000000000..9313f2a23 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-9.c @@ -0,0 +1,64 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char uX[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short uresult[N]; +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +short result[N]; + +/* Unsigned type promotion (qi->hi) */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + uresult[i] = (unsigned short)uX[i]; + } +} + +/* Signed type promotion (qi->hi) */ +__attribute__ ((noinline)) int +foo2(int len) { + int i; + + for (i=0; i<len; i++) { + result[i] = (short)X[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = 16-i; + uX[i] = 16-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (uresult[i] != (unsigned short)uX[i]) + abort (); + } + + foo2 (N); + + for (i=0; i<N; i++) { + if (result[i] != (short)X[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c new file mode 100644 index 000000000..84883ca19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float in[N] = {232,132,32,432,532,321,327,323,321,324,322,329,432,832,932,232}; +float out[N]; +float check_res[N] = {112,-4,-120,264,348,121,111,91,73,60,42,33,120,504,588,-128}; +float a[2*N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + +/* Outer-loop vectorization. */ + +__attribute__ ((noinline)) void +foo () +{ + int i, j; + float res; + + for (i = 0; i < N; i++) + { + res = in[i]; + + for (j = 0; j < N; j++) + res = res - a[i+j]; + + out[i] = res; + } + + for (i = 0; i < N; i++) + if (out[i] != check_res[i]) + abort (); + +} + +int main () +{ + check_vect (); + + foo(); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c new file mode 100644 index 000000000..22b1d98de --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float out[N]; +float check_res[N] = {880,864,848,832,816,800,784,768,752,736,720,704,688,672,656,640}; +float a[2*N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + +/* Outer-loop vectorization. */ + +__attribute__ ((noinline)) void +foo () +{ + int i, j; + float res; + + for (i = 0; i < N; i++) + { + res = 1000; + + for (j = 0; j < N; j++) + res = res - a[i+j]; + + out[i] = res; + } + + for (i = 0; i < N; i++) + if (out[i] != check_res[i]) + abort (); + +} + +int main () +{ + check_vect (); + + foo(); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-3.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-3.c new file mode 100644 index 000000000..0c8f91307 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-3.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 82 + +float c[N][N], b[N][N], a[N]; + +__attribute__ ((noinline)) int +main1 () +{ + int i, j; + float diff; + + /* In inner loop vectorization -funsafe-math-optimizations is needed to + vectorize the summation. But in outer loop vectorization the order of + calculation doesn't change, therefore, there is no need in that flag. */ + for (i = 0; i < N; i++) + { + diff = 2; + for (j = 0; j < N; j++) + diff += (b[j][i] - c[j][i]); + + a[i] = diff; + } + + /* Check results: */ + for (i = 0; i < N; i++) + if (a[i] != DIFF) + abort (); + + return 0; +} + +int main (void) +{ + int i, j; + + check_vect (); + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + { + b[i][j] = i+j+5; + c[i][j] = i+j; + } + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-1.c b/gcc/testsuite/gcc.dg/vect/vect-outer-1.c new file mode 100644 index 000000000..f0df5d4cd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +#define N 64 +signed short image[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short block[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short out[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* Can't do outer-loop vectorization because of non-consecutive access. */ + +void +foo (){ + int i,j; + int diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j+=8) { + diff += (image[i][j] - block[i][j]); + } + out[i]=diff; + } +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "strided access in outer loop" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-1a.c b/gcc/testsuite/gcc.dg/vect/vect-outer-1a.c new file mode 100644 index 000000000..f88dd2105 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-1a.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ + +#define N 64 +signed short image[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short block[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* Can't do outer-loop vectorization because of non-consecutive access. */ + +int +foo (){ + int i,j; + int diff = 0; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j+=8) { + diff += (image[i][j] - block[i][j]); + } + } + return diff; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "strided access in outer loop" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-1b.c b/gcc/testsuite/gcc.dg/vect/vect-outer-1b.c new file mode 100644 index 000000000..e093d0ea3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-1b.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +#define N 40 +signed short image[N][N]; +signed short block[N][N]; +signed short out[N]; + +/* Outer-loop cannot get vectorized because of non-consecutive access. */ + +void +foo (){ + int i,j; + int diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j+=4) { + diff += (image[i][j] - block[i][j]); + } + out[i]=diff; + } +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "strided access in outer loop" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-2.c b/gcc/testsuite/gcc.dg/vect/vect-outer-2.c new file mode 100644 index 000000000..38701977b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-2.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_intfloat_cvt } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float out[N]; + +/* Outer-loop vectorization. */ + +__attribute__ ((noinline)) void +foo (){ + int i,j; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + image[j][i] = j+i; + } + } +} + +int main (void) +{ + check_vect (); + int i, j; + + foo (); + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + if (image[j][i] != j+i) + abort (); + } + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-2a.c b/gcc/testsuite/gcc.dg/vect/vect-outer-2a.c new file mode 100644 index 000000000..b8d0e51fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-2a.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_intfloat_cvt } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[N][N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo (){ + int i,j,k; + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + image[k][j][i] = j+i+k; + } + } + } +} + +int main (void) +{ + check_vect (); + int i, j, k; + + foo (); + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + if (image[k][j][i] != j+i+k) + abort (); + } + } + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-2b.c b/gcc/testsuite/gcc.dg/vect/vect-outer-2b.c new file mode 100644 index 000000000..df2e6a7b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-2b.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_float } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[2*N][N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo (){ + int i,j,k; + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + image[k+i][j][i] = j+i+k; + } + } + } +} + +int main (void) +{ + check_vect (); + int i, j, k; + + foo (); + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + if (image[k+i][j][i] != j+i+k) + abort (); + } + } + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "strided access in outer loop." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-2c.c b/gcc/testsuite/gcc.dg/vect/vect-outer-2c.c new file mode 100644 index 000000000..0ca868637 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-2c.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_intfloat_cvt } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[2*N][2*N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo (){ + int i,j,k; + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < N; j+=2) { + image[k][j][i] = j+i+k; + } + } + } +} + +int main (void) +{ + check_vect (); + int i, j, k; + + foo (); + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < N; j+=2) { + if (image[k][j][i] != j+i+k) + abort (); + } + } + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-2d.c b/gcc/testsuite/gcc.dg/vect/vect-outer-2d.c new file mode 100644 index 000000000..3e19d47b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-2d.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_float } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[N][N][N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +__attribute__ ((noinline)) void +foo (){ + int i,j,k; + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < i+1; j++) { + image[k][j][i] = j+i+k; + } + } + } +} + +int main (void) +{ + check_vect (); + int i, j, k; + + foo (); + + for (k=0; k<N; k++) { + for (i = 0; i < N; i++) { + for (j = 0; j < i+1; j++) { + if (image[k][j][i] != j+i+k) + abort (); + } + } + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-3.c b/gcc/testsuite/gcc.dg/vect/vect-outer-3.c new file mode 100644 index 000000000..924700c58 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-3.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_float } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float out[N]; + +/* Outer-loop vectoriation. */ + +__attribute__ ((noinline)) void +foo (){ + int i,j; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j++) { + diff += image[j][i]; + } + out[i]=diff; + } +} + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + image[i][j]=i+j; + } + } + + foo (); + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j++) { + diff += image[j][i]; + } + if (out[i] != diff) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-3a.c b/gcc/testsuite/gcc.dg/vect/vect-outer-3a.c new file mode 100644 index 000000000..4b5107dcf --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-3a.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_float } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[N][N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float out[N]; + +/* Outer-loop vectorization with misaliged accesses in the inner-loop. */ + +__attribute__ ((noinline)) void +foo (){ + int i,j; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j++) { + diff += image[j][i]; + } + out[i]=diff; + } +} + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + image[i][j]=i+j; + } + } + + foo (); + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j++) { + diff += image[j][i]; + } + if (out[i] != diff) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "step doesn't divide the vector-size" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-3b.c b/gcc/testsuite/gcc.dg/vect/vect-outer-3b.c new file mode 100644 index 000000000..f11cb751c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-3b.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_float } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float out[N]; + +/* Outer-loop vectorization with non-consecutive access. Not vectorized yet. */ + +__attribute__ ((noinline)) void +foo (){ + int i,j; + float diff; + + for (i = 0; i < N/2; i++) { + diff = 0; + for (j = 0; j < N; j++) { + diff += image[j][2*i]; + } + out[i]=diff; + } +} + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + image[i][j]=i+j; + } + } + + foo (); + + for (i = 0; i < N/2; i++) { + diff = 0; + for (j = 0; j < N; j++) { + diff += image[j][2*i]; + } + if (out[i] != diff) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "strided access in outer loop" 2 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-3c.c b/gcc/testsuite/gcc.dg/vect/vect-outer-3c.c new file mode 100644 index 000000000..599137ba1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-3c.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_float } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +float image[N][N+1] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float out[N]; + +/* Outer-loop vectorization. */ + +__attribute__ ((noinline)) void +foo (){ + int i,j; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j+=4) { + diff += image[j][i]; + } + out[i]=diff; + } +} + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < N; i++) { + for (j = 0; j < N; j++) { + image[i][j]=i+j; + } + } + + foo (); + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < N; j+=4) { + diff += image[j][i]; + } + if (out[i] != diff) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4.c new file mode 100644 index 000000000..8f53f2553 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +#define M 128 +float in[N+M]; +float coeff[M]; +float out[N]; + +/* Outer-loop vectorization. */ + +__attribute__ ((noinline)) void +foo (){ + int i,j; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=4) { + diff += in[j+i]*coeff[j]; + } + out[i]=diff; + } +} + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < M; i++) + coeff[i] = i; + for (i = 0; i < N+M; i++) + in[i] = i; + + foo (); + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=4) { + diff += in[j+i]*coeff[j]; + } + if (out[i] != diff) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "zero step in outer loop." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4a.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4a.c new file mode 100644 index 000000000..d7bcc9a2e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4a.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +#define N 40 +#define M 128 +signed short in[N+M]; +signed short coeff[M]; +signed short out[N]; + +/* Outer-loop vectorization. */ + +void +foo (){ + int i,j; + int diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]*coeff[j]; + } + out[i]=diff; + } +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { target { vect_widen_mult_hi_to_si && vect_pack_trunc } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4b.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4b.c new file mode 100644 index 000000000..407315a8d --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4b.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ + +#define N 40 +#define M 128 +signed short in[N+M]; +signed short coeff[M]; +int out[N]; + +/* Outer-loop vectorization. */ + +void +foo (){ + int i,j; + int diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]*coeff[j]; + } + out[i]=diff; + } +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4c.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4c.c new file mode 100644 index 000000000..3342b79b2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4c.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +#define N 40 +#define M 128 +unsigned short in[N+M]; +unsigned short coeff[M]; +unsigned int out[N]; + +/* Outer-loop vectorization. */ + +void +foo (){ + int i,j; + unsigned short diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]*coeff[j]; + } + out[i]=diff; + } +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { target { vect_short_mult && { ! vect_no_align } } } } } */ +/* { dg-final { scan-tree-dump-times "zero step in outer loop." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4d.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4d.c new file mode 100644 index 000000000..c344fb1d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4d.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +#define M 128 +float in[N+M]; +float out[N]; + +/* Outer-loop vectorization. */ + +__attribute__ ((noinline)) void +foo (){ + int i,j; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=4) { + diff += in[j+i]; + } + out[i]=diff; + } +} + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < N; i++) + in[i] = i; + + foo (); + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=4) { + diff += in[j+i]; + } + if (out[i] != diff) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4e.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4e.c new file mode 100644 index 000000000..243cc1af7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4e.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ + +#define N 40 +#define M 128 +unsigned int in[N+M]; +unsigned short out[N]; + +/* Outer-loop vectorization. */ + +void +foo (){ + int i,j; + unsigned int diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + out[i]=(unsigned short)diff; + } + + return; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4f.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4f.c new file mode 100644 index 000000000..c6cc4a8d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4f.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 96 +#define M 128 +unsigned short in[N+M]; +unsigned int out[N]; +unsigned char arr[N]; + +/* Outer-loop vectorization. */ +/* Not vectorized due to multiple-types in the inner-loop. */ + +__attribute__ ((noinline)) unsigned int +foo (){ + int i,j; + unsigned int diff; + unsigned int s=0; + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + s+=diff; + } + return s; +} + +__attribute__ ((noinline)) unsigned int +bar (int i, unsigned int diff, unsigned short *in) +{ + int j; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + return diff; +} + +int main (void) +{ + int i, j; + unsigned int diff; + unsigned int s=0,sum=0; + + check_vect (); + + for (i = 0; i < N+M; i++) { + in[i] = i; + } + + sum=foo (); + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + diff = bar (i, diff, in); + s += diff; + } + + if (s != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4g.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4g.c new file mode 100644 index 000000000..c6cc4a8d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4g.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 96 +#define M 128 +unsigned short in[N+M]; +unsigned int out[N]; +unsigned char arr[N]; + +/* Outer-loop vectorization. */ +/* Not vectorized due to multiple-types in the inner-loop. */ + +__attribute__ ((noinline)) unsigned int +foo (){ + int i,j; + unsigned int diff; + unsigned int s=0; + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + s+=diff; + } + return s; +} + +__attribute__ ((noinline)) unsigned int +bar (int i, unsigned int diff, unsigned short *in) +{ + int j; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + return diff; +} + +int main (void) +{ + int i, j; + unsigned int diff; + unsigned int s=0,sum=0; + + check_vect (); + + for (i = 0; i < N+M; i++) { + in[i] = i; + } + + sum=foo (); + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + diff = bar (i, diff, in); + s += diff; + } + + if (s != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4i.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4i.c new file mode 100644 index 000000000..a244ac20a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4i.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 96 +#define M 128 +unsigned char in[N+M]; +unsigned short out[N]; + +/* Outer-loop vectorization. */ +/* Multiple-types in the inner-loop. */ + +__attribute__ ((noinline)) +unsigned short +foo (){ + int i,j; + unsigned short diff; + unsigned short s=0; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + s+=diff; + } + return s; +} + +int main (void) +{ + check_vect (); + int i; + unsigned short s; + + for (i = 0; i < N+M; i++) + in[i] = (unsigned char)i; + + s = foo (); + + if (s != 34048) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4j.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4j.c new file mode 100644 index 000000000..db8f61c5e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4j.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +#define N 96 +#define M 128 +unsigned char in[N+M]; +unsigned short out[N]; + +/* Outer-loop vectorization. */ + +void +foo (){ + int i,j; + unsigned short diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + out[i]=diff; + } +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4k.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4k.c new file mode 100644 index 000000000..c6cc4a8d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4k.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 96 +#define M 128 +unsigned short in[N+M]; +unsigned int out[N]; +unsigned char arr[N]; + +/* Outer-loop vectorization. */ +/* Not vectorized due to multiple-types in the inner-loop. */ + +__attribute__ ((noinline)) unsigned int +foo (){ + int i,j; + unsigned int diff; + unsigned int s=0; + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + s+=diff; + } + return s; +} + +__attribute__ ((noinline)) unsigned int +bar (int i, unsigned int diff, unsigned short *in) +{ + int j; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + return diff; +} + +int main (void) +{ + int i, j; + unsigned int diff; + unsigned int s=0,sum=0; + + check_vect (); + + for (i = 0; i < N+M; i++) { + in[i] = i; + } + + sum=foo (); + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + diff = bar (i, diff, in); + s += diff; + } + + if (s != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4l.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4l.c new file mode 100644 index 000000000..c6cc4a8d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4l.c @@ -0,0 +1,69 @@ +/* { dg-require-effective-target vect_int } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 96 +#define M 128 +unsigned short in[N+M]; +unsigned int out[N]; +unsigned char arr[N]; + +/* Outer-loop vectorization. */ +/* Not vectorized due to multiple-types in the inner-loop. */ + +__attribute__ ((noinline)) unsigned int +foo (){ + int i,j; + unsigned int diff; + unsigned int s=0; + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + s+=diff; + } + return s; +} + +__attribute__ ((noinline)) unsigned int +bar (int i, unsigned int diff, unsigned short *in) +{ + int j; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + return diff; +} + +int main (void) +{ + int i, j; + unsigned int diff; + unsigned int s=0,sum=0; + + check_vect (); + + for (i = 0; i < N+M; i++) { + in[i] = i; + } + + sum=foo (); + + for (i = 0; i < N; i++) { + arr[i] = 3; + diff = 0; + diff = bar (i, diff, in); + s += diff; + } + + if (s != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4m.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4m.c new file mode 100644 index 000000000..6e032f13c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4m.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +#define M 128 +unsigned short in[N+M]; +unsigned int out[N]; + +/* Outer-loop vectorization. */ +/* Not vectorized due to multiple-types in the inner-loop. */ + +__attribute__ ((noinline)) unsigned int +foo (){ + int i,j; + unsigned int diff; + unsigned int s=0; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + s+=((unsigned short)diff>>3); + } + return s; +} + +int main (void) +{ + int i, j; + unsigned int diff; + unsigned int s=0,sum=0; + + check_vect (); + + for (i = 0; i < N+M; i++) { + in[i] = i; + } + + sum=foo (); + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j+=8) { + diff += in[j+i]; + } + s += ((unsigned short)diff>>3); + } + + if (s != sum) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-5.c b/gcc/testsuite/gcc.dg/vect/vect-outer-5.c new file mode 100644 index 000000000..f5027d626 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-5.c @@ -0,0 +1,83 @@ +/* { dg-require-effective-target vect_float } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 64 +#define MAX 42 + +extern void abort(void); + +__attribute__ ((noinline)) +int main1 () +{ + float A[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float B[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float C[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float D[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + float E[4] = {0,1,2,480}; + float s; + + int i, j; + + for (i = 0; i < N; i++) + { + A[i] = i; + B[i] = i; + C[i] = i; + D[i] = i; + } + + /* Outer-loop 1: Vectorizable with respect to dependence distance. */ + for (i = 0; i < N-20; i++) + { + s = 0; + for (j=0; j<N; j+=4) + s += C[j]; + A[i] = A[i+20] + s; + } + + /* check results: */ + for (i = 0; i < N-20; i++) + { + s = 0; + for (j=0; j<N; j+=4) + s += C[j]; + if (A[i] != D[i+20] + s) + abort (); + } + + /* Outer-loop 2: Not vectorizable because of dependence distance. */ + for (i = 0; i < 4; i++) + { + s = 0; + for (j=0; j<N; j+=4) + s += C[j]; + B[i+3] = B[i] + s; + } + + /* check results: */ + for (i = 0; i < 4; i++) + { + if (B[i] != E[i]) + abort (); + } + + return 0; +} + +int main () +{ + check_vect (); + return main1(); +} + +/* NOTE: We temporarily xfail the following check until versioning for + aliasing is fixed to avoid versioning when the dependence distance + is known. */ +/* { dg-final { scan-tree-dump-times "not vectorized: possible dependence between data-refs" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "zero step in outer loop." 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-6.c b/gcc/testsuite/gcc.dg/vect/vect-outer-6.c new file mode 100644 index 000000000..572f433cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-6.c @@ -0,0 +1,66 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include <signal.h> +#include "tree-vect.h" + +#define N 64 +#define MAX 42 + +float A[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float B[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float C[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +float D[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +extern void abort(void); + +__attribute__ ((noinline)) +int main1 () +{ + float s; + + int i, j; + + for (i = 0; i < N; i++) + { + s = 0; + for (j = 0; j < N; j += 4) + s += C[j]; + A[i] = s; + } + + return 0; +} + +int main () +{ + int i,j; + float s; + + check_vect (); + + for (i = 0; i < N; i++) + { + A[i] = i; + B[i] = i; + C[i] = i; + D[i] = i; + } + + main1(); + + /* check results: */ + for (i = 0; i < N; i++) + { + s = 0; + for (j = 0; j < N; j += 4) + s += C[j]; + if (A[i] != s) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "zero step in outer loop." 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb.c b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb.c new file mode 100644 index 000000000..3c1a362c0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-fir-lb.c @@ -0,0 +1,78 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +#define M 64 +float in[N+M]; +float coeff[M]; +float out[N]; +float fir_out[N]; + +/* Vectorized. Fixed misaligment in the inner-loop. */ +__attribute__ ((noinline)) +void foo (){ + int i,j,k; + float diff; + + for (i = 0; i < N; i++) { + out[i] = 0; + } + + for (k = 0; k < 4; k++) { + for (i = 0; i < N; i++) { + diff = 0; + j = k; + + do { + diff += in[j+i]*coeff[j]; + j+=4; + } while (j < M); + + out[i] += diff; + } + } + +} + +/* Vectorized. Changing misalignment in the inner-loop. */ +__attribute__ ((noinline)) +void fir (){ + int i,j,k; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j++) { + diff += in[j+i]*coeff[j]; + } + fir_out[i] = diff; + } +} + + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < M; i++) + coeff[i] = i; + for (i = 0; i < N+M; i++) + in[i] = i; + + foo (); + fir (); + + for (i = 0; i < N; i++) { + if (out[i] != fir_out[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-fir.c b/gcc/testsuite/gcc.dg/vect/vect-outer-fir.c new file mode 100644 index 000000000..af787b96a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-outer-fir.c @@ -0,0 +1,74 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 40 +#define M 128 +float in[N+M]; +float coeff[M]; +float out[N]; +float fir_out[N]; + +/* Should be vectorized. Fixed misaligment in the inner-loop. */ +__attribute__ ((noinline)) +void foo (){ + int i,j,k; + float diff; + + for (i = 0; i < N; i++) { + out[i] = 0; + } + + for (k = 0; k < 4; k++) { + for (i = 0; i < N; i++) { + diff = 0; + for (j = k; j < M; j+=4) { + diff += in[j+i]*coeff[j]; + } + out[i] += diff; + } + } + +} + +/* Vectorized. Changing misalignment in the inner-loop. */ +__attribute__ ((noinline)) +void fir (){ + int i,j,k; + float diff; + + for (i = 0; i < N; i++) { + diff = 0; + for (j = 0; j < M; j++) { + diff += in[j+i]*coeff[j]; + } + fir_out[i] = diff; + } +} + + +int main (void) +{ + check_vect (); + int i, j; + float diff; + + for (i = 0; i < M; i++) + coeff[i] = i; + for (i = 0; i < N+M; i++) + in[i] = i; + + foo (); + fir (); + + for (i = 0; i < N; i++) { + if (out[i] != fir_out[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 2 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-1.c b/gcc/testsuite/gcc.dg/vect/vect-peel-1.c new file mode 100644 index 000000000..8aca27ca1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-1.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int ib[N+7]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + int ia[N+1]; + + /* All the accesses are misaligned. With cost model disabled, we count the + the number of aligned accesses for each peeling option, and in this case + we align the two loads if possible (i.e., if misaligned stores are + supported). */ + for (i = 1; i <= N; i++) + { + ia[i] = ib[i+2] + ib[i+6]; + } + + /* check results: */ + for (i = 1; i <= N; i++) + { + if (ia[i] != ib[i+2] + ib[i+6]) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i <= N+6; i++) + { + asm volatile ("" : "+r" (i)); + ib[i] = i; + } + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { { vect_element_align } && { vect_aligned_arrays } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-2.c b/gcc/testsuite/gcc.dg/vect/vect-peel-2.c new file mode 100644 index 000000000..f6942d458 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-2.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ +/* { dg-add-options quad_vectors } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +/* unaligned store. */ + +int ib[N+7]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + int ia[N+1]; + + /* The store is aligned and the loads are misaligned with the same + misalignment. Cost model is disabled. If misaligned stores are supported, + we peel according to the loads to align them. */ + for (i = 0; i <= N; i++) + { + ia[i] = ib[i+2] + ib[i+6]; + } + + /* check results: */ + for (i = 1; i <= N; i++) + { + if (ia[i] != ib[i+2] + ib[i+6]) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i <= N+6; i++) + { + asm volatile ("" : "+r" (i)); + ib[i] = i; + } + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { { vect_element_align } && { vect_aligned_arrays } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { { vect_element_align } && { vect_aligned_arrays } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-3.c b/gcc/testsuite/gcc.dg/vect/vect-peel-3.c new file mode 100644 index 000000000..8f4d35714 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-3.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 +#define RES 21640 + +int ib[N+10]; +int ia[N+10]; +int ic[N+10]; + +__attribute__ ((noinline)) +int main1 () +{ + int i, suma = 0, sumb = 0, sumc = 0; + + /* ib and ic have same misalignment, we peel to align them. */ + for (i = 0; i <= N; i++) + { + suma += ia[i]; + sumb += ib[i+5]; + sumc += ic[i+1]; + } + + /* check results: */ + if (suma + sumb + sumc != RES) + abort (); + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i < N+10; i++) + { + asm volatile ("" : "+r" (i)); + ib[i] = i; + ic[i] = i+2; + ia[i] = i/2; + } + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-peel-4.c b/gcc/testsuite/gcc.dg/vect/vect-peel-4.c new file mode 100644 index 000000000..1b47f2682 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-peel-4.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +int ib[N+7]; + +__attribute__ ((noinline)) +int main1 () +{ + int i; + int ia[N+1]; + + /* Don't peel keeping one load and the store aligned. */ + for (i = 0; i <= N; i++) + { + ia[i] = ib[i] + ib[i+5]; + } + + /* check results: */ + for (i = 1; i <= N; i++) + { + if (ia[i] != ib[i] + ib[i+5]) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + for (i = 0; i <= N+6; i++) + { + asm volatile ("" : "+r" (i)); + ib[i] = i; + } + + return main1 (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c new file mode 100644 index 000000000..096839f9c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-pre-interact.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +/* This checks that PRE doesn't create situations that prevent vectorization. + I.e. PR39300, PR35229. */ +float res[1024], data[1025]; + +void foo (void) +{ + int i; + for (i = 0; i < 1024; ++i) + res[i] = data[i] + data[i + 1]; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-recip.c b/gcc/testsuite/gcc.dg/vect/vect-recip.c new file mode 100644 index 000000000..4f130b05c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-recip.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ + +void f(float *__restrict__ qa, float *__restrict__ qb, + float *__restrict__ qc, float *__restrict__ rtrms) +{ + int i; + static float qam[600]; + static float qbm[600]; + static float qcm[600]; + for(i=0;i<600;i++) + { + float a = rtrms[i]; + qam[i] = qa[i]/a; + qbm[i] = qb[i]/a; + qcm[i] = qc[i]/a; + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-1.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-1.c new file mode 100644 index 000000000..dbb154d12 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-1.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +unsigned int ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Test vectorization of reduction of unsigned-int. */ + +__attribute__ ((noinline)) +void main1 (unsigned int x, unsigned int max_result, unsigned int min_result) +{ + int i; + unsigned int udiff = 2; + unsigned int umax = x; + unsigned int umin = x; + + /* Summation. */ + for (i = 0; i < N; i++) { + udiff += (ub[i] - uc[i]); + } + + /* Maximum. */ + for (i = 0; i < N; i++) { + umax = umax < uc[i] ? uc[i] : umax; + } + + /* Minimum. */ + for (i = 0; i < N; i++) { + umin = umin > uc[i] ? uc[i] : umin; + } + + /* check results: */ + if (udiff != DIFF) + abort (); + if (umax != max_result) + abort (); + if (umin != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail { vect_no_int_add || vect_no_int_max } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-1char.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-1char.c new file mode 100644 index 000000000..5a1c03d11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-1char.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +unsigned char ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned char uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) void +main1 (unsigned char x, unsigned char max_result, unsigned char min_result) +{ + int i; + unsigned char udiff = 2; + unsigned char umax = x; + unsigned char umin = x; + + for (i = 0; i < N; i++) { + udiff += (unsigned char)(ub[i] - uc[i]); + } + + for (i = 0; i < N; i++) { + umax = umax < uc[i] ? uc[i] : umax; + } + + for (i = 0; i < N; i++) { + umin = umin > uc[i] ? uc[i] : umin; + } + + /* check results: */ + if (udiff != DIFF) + abort (); + if (umax != max_result) + abort (); + if (umin != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-1short.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-1short.c new file mode 100644 index 000000000..145722a19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-1short.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +unsigned short ub[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned short uc[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) void +main1 (unsigned short x, unsigned short max_result, unsigned short min_result) +{ + int i; + unsigned short udiff = 2; + unsigned short umax = x; + unsigned short umin = x; + + for (i = 0; i < N; i++) { + udiff += (unsigned short)(ub[i] - uc[i]); + } + + for (i = 0; i < N; i++) { + umax = umax < uc[i] ? uc[i] : umax; + } + + for (i = 0; i < N; i++) { + umin = umin > uc[i] ? uc[i] : umin; + } + + /* check results: */ + if (udiff != DIFF) + abort (); + if (umax != max_result) + abort (); + if (umin != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-2.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-2.c new file mode 100644 index 000000000..912e69c93 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-2.c @@ -0,0 +1,53 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 240 + +int b[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +int c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Test vectorization of reduction of signed-int. */ + +__attribute__ ((noinline)) +void main1 (int x, int max_result, int min_result) +{ + int i; + int diff = 0; + int max = x; + int min = x; + + for (i = 0; i < N; i++) { + diff += (b[i] - c[i]); + } + + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail { vect_no_int_add || vect_no_int_max } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-2char.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-2char.c new file mode 100644 index 000000000..6d01f0317 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-2char.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 121 + +__attribute__ ((noinline)) +void main1 (signed char x, signed char max_result, signed char min_result) +{ + int i; + signed char b[N] = {1,2,3,6,8,10,12,14,16,18,20,22,24,26,28,30}; + signed char c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + signed char diff = 2; + signed char max = x; + signed char min = x; + + for (i = 0; i < N; i++) { + diff += (signed char)(b[i] - c[i]); + } + + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-2short.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-2short.c new file mode 100644 index 000000000..7d19e7001 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-2short.c @@ -0,0 +1,49 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +__attribute__ ((noinline)) +void main1 (short x, short max_result, short min_result) +{ + int i; + short b[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + short c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + short diff = 2; + short max = x; + short min = x; + + for (i = 0; i < N; i++) { + diff += (short)(b[i] - c[i]); + } + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-3.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-3.c new file mode 100644 index 000000000..3e6f17c48 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-3.c @@ -0,0 +1,42 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +unsigned int ub[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +unsigned int uc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +/* Test vectorization of reduction of unsigned-int in the presence + of unknown-loop-bound. */ + +__attribute__ ((noinline)) +int main1 (int n, int res) +{ + int i; + unsigned int udiff; + + udiff = 0; + for (i = 0; i < n; i++) { + udiff += (ub[i] - uc[i]); + } + + /* check results: */ + if (udiff != res) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (N, 240); + main1 (N-1, 210); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-6.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-6.c new file mode 100644 index 000000000..3f8e2ec69 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-6.c @@ -0,0 +1,54 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +__attribute__ ((noinline)) +int main1 (float x, float max_result) +{ + int i; + float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; + float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + float diff = 2; + float max = x; + float min = 10; + + for (i = 0; i < N; i++) { + diff += (b[i] - c[i]); + } + + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != 0) + abort (); + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (100 ,100); + main1 (0, 15); + return 0; +} + +/* need -ffast-math to vectorizer these loops. */ +/* ARM NEON passes -ffast-math to these tests, so expect this to fail. */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { xfail arm_neon_ok } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-7.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-7.c new file mode 100644 index 000000000..a59a24ac7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-7.c @@ -0,0 +1,78 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +#define N 32 + +extern void abort (void); +typedef unsigned char T; + +__attribute__ ((noinline)) void +testmax (const T *c, T init, T result) +{ + T lc[N], accum = init; + int i; + + __builtin_memcpy (lc, c, sizeof(lc)); + + for (i = 0; i < N; i++) { + accum = accum < lc[i] ? lc[i] : accum; + } + + if (accum != result) + abort (); +} + +__attribute__ ((noinline)) void +testmin (const T *c, T init, T result) +{ + T lc[N], accum = init; + int i; + + __builtin_memcpy (lc, c, sizeof(lc)); + + for (i = 0; i < N; i++) { + accum = accum > lc[i] ? lc[i] : accum; + } + + if (accum != result) + abort (); +} + +int main (void) +{ + static unsigned char const A[N] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f + }; + + static unsigned char const B[N] = { + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f + }; + + static unsigned char const C[N] = { + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + }; + + check_vect (); + + testmin (A, 10, 1); + testmin (B, 0x7f, 0x70); + testmin (C, 0x7f, 0x09); + + testmax (A, 0, 0x7f); + testmax (B, 0, 0x8f); + testmax (C, 0, 0xff); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-8.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-8.c new file mode 100644 index 000000000..fdfec0a8b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-8.c @@ -0,0 +1,78 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +#define N 32 + +extern void abort (void); +typedef signed char T; + +__attribute__ ((noinline)) void +testmax (const T *c, T init, T result) +{ + T lc[N], accum = init; + int i; + + __builtin_memcpy (lc, c, sizeof(lc)); + + for (i = 0; i < N; i++) { + accum = accum < lc[i] ? lc[i] : accum; + } + + if (accum != result) + abort (); +} + +__attribute__ ((noinline)) void +testmin (const T *c, T init, T result) +{ + T lc[N], accum = init; + int i; + + __builtin_memcpy (lc, c, sizeof(lc)); + + for (i = 0; i < N; i++) { + accum = accum > lc[i] ? lc[i] : accum; + } + + if (accum != result) + abort (); +} + +int main (void) +{ + static signed char const A[N] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f + }; + + static signed char const B[N] = { + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f + }; + + static signed char const C[N] = { + 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + }; + + check_vect (); + + testmin (A, 0, 0); + testmin (B, 0, 0x80); + testmin (C, 0, 0x80); + + testmax (A, 0, 0x7f); + testmax (B, 0, 0x7f); + testmax (C, 0, 0x77); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-9.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-9.c new file mode 100644 index 000000000..ecf3bf1ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-9.c @@ -0,0 +1,78 @@ +/* { dg-require-effective-target vect_int } */ + +#include "tree-vect.h" + +#define N 32 + +extern void abort (void); +typedef unsigned short T; + +__attribute__ ((noinline)) void +testmax (const T *c, T init, T result) +{ + T lc[N], accum = init; + int i; + + __builtin_memcpy (lc, c, sizeof(lc)); + + for (i = 0; i < N; i++) { + accum = accum < lc[i] ? lc[i] : accum; + } + + if (accum != result) + abort (); +} + +__attribute__ ((noinline)) void +testmin (const T *c, T init, T result) +{ + T lc[N], accum = init; + int i; + + __builtin_memcpy (lc, c, sizeof(lc)); + + for (i = 0; i < N; i++) { + accum = accum > lc[i] ? lc[i] : accum; + } + + if (accum != result) + abort (); +} + +int main (void) +{ + static unsigned short const A[N] = { + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff + }; + + static unsigned short const B[N] = { + 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, + 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, + 0x8008, 0x8009, 0x800a, 0x800b, 0x800c, 0x800d, 0x800e, 0x800f + }; + + static unsigned short const C[N] = { + 0xffff, 0xfffe, 0xfffd, 0xfffc, 0xfffb, 0xfffa, 0xfff9, 0xfff8, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, + 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, + }; + + check_vect (); + + testmin (A, 10, 1); + testmin (B, 0x7fff, 0x7000); + testmin (C, 0x7fff, 0x0009); + + testmax (A, 0, 0x7fff); + testmax (B, 0, 0x800f); + testmax (C, 0, 0xffff); + + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16a.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16a.c new file mode 100644 index 000000000..c98634416 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16a.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 +#define DOT 43680 + +signed short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* short->int->int dot product. + Detected as a dot-product pattern. + Vectorized on targets that support dot-product for signed shorts. */ + +__attribute__ ((noinline)) int +foo (int len) +{ + int i; + int result = 0; + + for (i = 0; i < len; i++) + { + result += (X[i] * Y[i]); + } + return result; +} + + +int +main (void) +{ + int i; + int dot; + + check_vect (); + + for (i = 0; i < N; i++) + { + X[i] = i; + Y[i] = N - i; + __asm__ volatile (""); + } + + dot = foo (N); + if (dot != DOT) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_sdot_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16b.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16b.c new file mode 100644 index 000000000..1344ca955 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s16b.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT 43680 + +signed short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* short->short->int dot product. Should be vectorized on architectures + supporting vectorized multiplication of two short args with short result, + e.g "mulv4hi3" and widenning sum */ +__attribute__ ((noinline)) int +foo (int len) +{ + int i; + int result = 0; + short prod; + + for (i = 0; i < len; i++) + { + prod = X[i] * Y[i]; + result += prod; + } + return result; +} + +int +main (void) +{ + int i, dot; + + check_vect (); + + for (i = 0; i < N; i++) + { + X[i] = i; + Y[i] = 64 - i; + __asm__ volatile (""); + } + + dot = foo (N); + if (dot != DOT) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_short_mult && { vect_widen_sum_hi_to_si || vect_unpack } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_short_mult } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { { ! vect_widen_sum_hi_to_si } && { ! vect_unpack } } } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8a.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8a.c new file mode 100644 index 000000000..96c2950c0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8a.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT1 43680 + +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* char->short->int dot product. + The dot-product pattern should be detected. + Vectorizable on vect_sdot_qi targets (targets that support dot-product of + signed chars). + + In the future could also be vectorized as widening-mult + widening-summation, + or with type-conversion support. + */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + int result = 0; + short prod; + + for (i=0; i<len; i++) { + prod = X[i] * Y[i]; + result += prod; + } + return result; +} + +int main (void) +{ + int i, dot1; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + dot1 = foo1 (N); + if (dot1 != DOT1) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_sdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_qi_to_hi && vect_widen_sum_hi_to_si } } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8b.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8b.c new file mode 100644 index 000000000..53a240118 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8b.c @@ -0,0 +1,65 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT2 -21856 + +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* char->short->short dot product. + The dot-product pattern should be detected. + The reduction is currently not vectorized becaus of the signed->unsigned->signed + casts, since this patch: + + 2005-12-26 Kazu Hirata <kazu@codesourcery.com> + + PR tree-optimization/25125 + + When the dot-product is detected, the loop should be vectorized on vect_sdot_qi + targets (targets that support dot-product of signed char). + This test would currently fail to vectorize on targets that support + dot-product of chars into an int accumulator. + Alternatively, the loop could also be vectorized as widening-mult + summation, + or with type-conversion support. + */ +__attribute__ ((noinline)) short +foo2(int len) { + int i; + short result = 0; + + for (i=0; i<len; i++) { + result += (X[i] * Y[i]); + } + return result; +} + +int main (void) +{ + int i; + short dot2; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + dot2 = foo2 (N); + if (dot2 != DOT2) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" } } */ + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8c.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8c.c new file mode 100644 index 000000000..59b174e3f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-s8c.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT3 43680 + +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* char->int->int dot product. + Not detected as a dot-product pattern. */ +__attribute__ ((noinline)) int +foo3(int len) { + int i; + int result = 0; + + for (i=0; i<len; i++) { + result += (X[i] * Y[i]); + } + return result; +} + +int main (void) +{ + int i, dot3; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + dot3 = foo3 (N); + if (dot3 != DOT3) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16a.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16a.c new file mode 100644 index 000000000..c09750d44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16a.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT1 43680 +#define DOT2 43680 + +unsigned short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* short->short->int dot product. + Not detected as a dot-product pattern. + Requires support for non-widneing multiplication and widening-summation. */ +__attribute__ ((noinline)) unsigned int +foo1(int len) { + int i; + unsigned int result = 0; + unsigned short prod; + + for (i=0; i<len; i++) { + prod = X[i] * Y[i]; + result += prod; + } + return result; +} + +int main (void) +{ + unsigned int dot1; + unsigned short i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + } + + dot1 = foo1 (N); + if (dot1 != DOT1) + abort (); + + return 0; +} + +/* The initialization loop in main also gets vectorized. */ +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target { vect_short_mult && vect_widen_sum_hi_to_si } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16b.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16b.c new file mode 100644 index 000000000..42b104fb8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16b.c @@ -0,0 +1,59 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT2 43680 + +unsigned short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); + +/* short->int->int dot product. + Currently not detected as a dot-product pattern: the multiplication + promotes the ushorts to int, and then the product is promoted to unsigned + int for the addition. Which results in an int->unsigned int cast, which + since no bits are modified in the cast should be trivially vectorizable. */ +__attribute__ ((noinline)) unsigned int +foo2(int len) { + int i; + unsigned int result = 0; + + for (i=0; i<len; i++) { + result += (X[i] * Y[i]); + } + return result; +} + + +int main (void) +{ + unsigned int dot2; + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + dot2 = foo2 (N); + if (dot2 != DOT2) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" { xfail *-*-* } } } */ + +/* Once the dot-product pattern is detected, we expect + that loop to be vectorized on vect_udot_hi targets (targets that support + dot-product of unsigned shorts) and targets that support widening multiplication. */ +/* The induction loop in main is vectorized. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u8a.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u8a.c new file mode 100644 index 000000000..d856754c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u8a.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT 43680 + +unsigned char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; + +/* char->short->int dot product. + Detected as a dot-product pattern. + Should be vectorized on targets that support dot-product for unsigned chars + (vect_udot_qi), + and on targets that support widening-multiplication and widening-summation + (vect_widen_mult_qi && vec_widen_sum_qi_to_si). + Widening-multiplication can also be supported by type promotion and non-widening + multiplication (vect_unpack && vect_short_mult); + Widening summation can also be supported by type promotion and non-widening + summation (vect_unpack). + */ +__attribute__ ((noinline)) unsigned int +foo (int len) { + int i; + unsigned int result = 0; + unsigned short prod; + + for (i=0; i<len; i++) { + prod = X[i] * Y[i]; + result += prod; + } + return result; +} + +int main (void) +{ + unsigned int dot; + int i; + + check_vect (); + + dot = foo (N); + if (dot != DOT) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_udot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_qi_to_hi && vect_widen_sum_qi_to_si } } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u8b.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u8b.c new file mode 100644 index 000000000..01c82b52c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u8b.c @@ -0,0 +1,55 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT 43680 + +unsigned char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +unsigned char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; + +/* char->short->short dot product. + Detected as a dot-product pattern. + Should be vectorized on targets that support dot-product for unsigned chars, + but currently this test cannot be vectorized as a dot-product on targets + that support char->short->int dot-product. + Alternatively, this test can be vectorized using vect_widen_mult_qi (or + vect_unpack and non-widening multplication: vect_unpack && vect_short_mult). + */ +__attribute__ ((noinline)) unsigned short +foo (int len) { + int i; + unsigned short result = 0; + + for (i=0; i<len; i++) { + result += (unsigned short)(X[i] * Y[i]); + } + return result; +} + +int main (void) +{ + unsigned short dot; + int i; + + check_vect (); + + dot = foo (N); + if (dot != DOT) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" } } */ + +/* When the vectorizer is enhanced to vectorize accumulation into short for + targets that support accumulation into int (powerpc, ia64) we'd have: +dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_udot_qi || vect_widen_mult_qi_to_hi } } +*/ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {target { vect_widen_mult_qi_to_hi || vect_unpack } } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1a.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1a.c new file mode 100644 index 000000000..2d5c5b9a8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1a.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +unsigned short udata_sh[N] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 }; +#define SUM 210 + +__attribute__ ((noinline)) int +foo () +{ + int i; + unsigned int intsum = 0; + + /* widenning sum: sum shorts into int. */ + for (i = 0; i < N; i++) + { + intsum += udata_sh[i]; + } + + /* check results: */ + if (intsum != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (); +} + +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_sum_hi_to_si } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_widen_sum_hi_to_si } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1b.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1b.c new file mode 100644 index 000000000..6effa87eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1b.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +unsigned char udata_ch[N] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 }; +#define SUM 210 + +__attribute__ ((noinline)) int +foo () +{ + int i; + unsigned int intsum = 0; + + /* widenning sum: sum chars into int. */ + for (i = 0; i < N; i++) + { + intsum += udata_ch[i]; + } + + /* check results: */ + if (intsum != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (); +} + +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_sum_qi_to_si || vect_unpack } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { { ! vect_widen_sum_qi_to_si } && { ! vect_unpack } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1c.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1c.c new file mode 100644 index 000000000..872e6e82e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-1c.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +unsigned char udata_ch[N] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 }; +#define SUM 210 + +__attribute__ ((noinline)) int +foo () +{ + int i; + unsigned short shortsum = 0; + + /* widenning sum: sum chars into short. */ + for (i = 0; i < N; i++) + { + shortsum += udata_ch[i]; + } + + /* check results: */ + if (shortsum != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (); +} + +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_sum_qi_to_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_widen_sum_qi_to_hi } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2a.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2a.c new file mode 100644 index 000000000..695738629 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2a.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +signed short data_sh[N] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 }; +#define SUM 210 + +__attribute__ ((noinline)) int +foo () +{ + int i; + signed int intsum = 0; + + /* widenning sum: sum shorts into int. */ + for (i = 0; i < N; i++) + { + intsum += data_sh[i]; + } + + /* check results: */ + if (intsum != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (); +} + +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_sum_hi_to_si } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_widen_sum_hi_to_si } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2b.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2b.c new file mode 100644 index 000000000..53d5f0d5c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2b.c @@ -0,0 +1,40 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +signed char data_ch[N] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 }; +#define SUM 210 + +__attribute__ ((noinline)) int +foo () +{ + int i; + signed int intsum = 0; + + /* widenning sum: sum chars into int. */ + for (i = 0; i < N; i++) + { + intsum += data_ch[i]; + } + + /* check results: */ + if (intsum != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (); +} + +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_sum_qi_to_si && vect_unpack } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { { ! vect_widen_sum_qi_to_si } && { ! vect_unpack } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2c.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2c.c new file mode 100644 index 000000000..36f51496f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-pattern-2c.c @@ -0,0 +1,48 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +signed char data_ch[N] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 }; +#define SUM 210 + +__attribute__ ((noinline)) int +foo () +{ + int i; + signed short shortsum = 0; + + /* widenning sum: sum chars into short. + The widening-summation pattern is currently not detected because of this + patch: + + 2005-12-26 Kazu Hirata <kazu@codesourcery.com> + + PR tree-optimization/25125 + */ + + for (i = 0; i < N; i++) + { + shortsum += data_ch[i]; + } + + /* check results: */ + if (shortsum != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (); +} + +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_widen_sum_qi_to_hi } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-shift-1.c b/gcc/testsuite/gcc.dg/vect/vect-shift-1.c new file mode 100644 index 000000000..79699047e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-shift-1.c @@ -0,0 +1,32 @@ +/* { dg-require-effective-target vect_shift } */ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 8 + +unsigned int A[N] = { 0x08000000, 0x08000001, 0x0ff0000ff, 0xf0000001, + 0x08000000, 0x08000001, 0x0ff0000ff, 0xf0000001 }; +unsigned int B[N] = { 0x01000000, 0x01000000, 0x01fe0001f, 0x1e000000, + 0x01000000, 0x01000000, 0x01fe0001f, 0x1e000000 }; + +int main () +{ + int i; + + check_vect (); + + for (i = 0; i < N; i++) + A[i] = A[i] >> 3; + + /* check results: */ + for (i = 0; i < N; i++) + if (A[i] != B[i]) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-shift-2.c b/gcc/testsuite/gcc.dg/vect/vect-shift-2.c new file mode 100644 index 000000000..83211eba4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-shift-2.c @@ -0,0 +1,190 @@ +/* { dg-require-effective-target vect_shift } */ +/* { dg-require-effective-target vect_int } */ +/* Check the standard integer types for left and right shifts to see if the + compiler replaced a scalar instruction with a vector instruction whether the + correct value is generated. */ + +#ifdef TRACE +#endif + +#include <stdarg.h> +#include "tree-vect.h" + +#ifndef ALIGN +#define ALIGN __attribute__((__aligned__(__BIGGEST_ALIGNMENT__))) +#endif + +#ifndef NOINLINE +#define NOINLINE __attribute__((__noinline__)) +#endif + +#ifdef TRACE +#define TRACE_FUNC(PREFIX, NAME) printf (#PREFIX #NAME "\n") +#define TRACE_DONE() printf ("done!\n") +#define TRACE_ABORT(I,E,G) \ +do { \ + printf ("Element %d, expected 0x%lx, got 0x%lx\n", \ + I, (long)(E), (long)(G)); \ + abort (); \ +} while (0) + +#else +#define TRACE_FUNC(PREFIX, A) +#define TRACE_DONE() +#define TRACE_ABORT(I,E,G) abort () +#endif + +#define NAME(A,B) A ## B + +#define VECT_TESTS(PREFIX, TYPE, N) \ + /* Restrict the optimizer from optimizing the setup loops. */ \ +volatile TYPE NAME (PREFIX, zero) = 0; \ + \ +TYPE NAME (PREFIX, a)[N] ALIGN; \ +TYPE NAME (PREFIX, b)[N] ALIGN; \ +TYPE NAME (PREFIX, c)[N] ALIGN; \ +TYPE NAME (PREFIX, d)[N] ALIGN; \ + \ +static void NOINLINE \ +NAME (PREFIX, lshift_2) (void) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, lshift_2); \ + for (i = 0; i < N; i++) \ + NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] << 2; \ +} \ + \ +static void NOINLINE \ +NAME (PREFIX, lshift_var) (int shift) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, lshift_var); \ + for (i = 0; i < N; i++) \ + NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] << shift; \ +} \ + \ +static void NOINLINE \ +NAME (PREFIX, lshift_vect) (void) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, lshift_vect); \ + for (i = 0; i < N; i++) \ + NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] << NAME (PREFIX, c)[i]; \ +} \ + \ +static void NOINLINE \ +NAME (PREFIX, rshift_2) (void) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, rshift_2); \ + for (i = 0; i < N; i++) \ + NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] >> 2; \ +} \ + \ +static void NOINLINE \ +NAME (PREFIX, rshift_var) (int shift) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, rshift_var); \ + for (i = 0; i < N; i++) \ + NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] >> shift; \ +} \ + \ +static void NOINLINE \ +NAME (PREFIX, rshift_vect) (void) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, rshift_vect); \ + for (i = 0; i < N; i++) \ + NAME (PREFIX, a)[i] = NAME (PREFIX, b)[i] >> NAME (PREFIX, c)[i]; \ +} \ + \ +static void NOINLINE \ +NAME (PREFIX, check) (void) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, check); \ + for (i = 0; i < N; i++) \ + if (NAME (PREFIX, a)[i] != NAME (PREFIX, d)[i]) \ + TRACE_ABORT (i, NAME (PREFIX, d)[i], NAME (PREFIX, a)[i]); \ +} \ + \ +static void NOINLINE \ +NAME (PREFIX, tests) (void) \ +{ \ + int i; \ + \ + TRACE_FUNC (PREFIX, tests); \ + for (i = 0; i < N; i++) \ + { \ + NAME (PREFIX, b)[i] = (i + NAME (PREFIX, zero)); \ + NAME (PREFIX, c)[i] = 2; \ + NAME (PREFIX, d)[i] = (i + NAME (PREFIX, zero)) << 2; \ + } \ + \ + NAME (PREFIX, lshift_2) (); \ + NAME (PREFIX, check) (); \ + \ + NAME (PREFIX, lshift_var) (2); \ + NAME (PREFIX, check) (); \ + \ + NAME (PREFIX, lshift_vect) (); \ + NAME (PREFIX, check) (); \ + \ + for (i = 0; i < N; i++) \ + { \ + NAME (PREFIX, b)[i] = ((i + NAME (PREFIX, zero)) << 4) \ + | (((TYPE)0x80) << ((sizeof (TYPE) * 8) - 8)); \ + NAME (PREFIX, c)[i] = 2; \ + NAME (PREFIX, d)[i] = (TYPE)((NAME (PREFIX, b)[i] \ + + NAME (PREFIX, zero)) >> 2); \ + } \ + \ + NAME (PREFIX, rshift_2) (); \ + NAME (PREFIX, check) (); \ + \ + NAME (PREFIX, rshift_var) (2); \ + NAME (PREFIX, check) (); \ + \ + NAME (PREFIX, rshift_vect) (); \ + NAME (PREFIX, check) (); \ +} + +VECT_TESTS(uc_, unsigned char, 16) +VECT_TESTS(us_, unsigned short, 32) +VECT_TESTS(ui_, unsigned int, 32) +VECT_TESTS(ul_, unsigned long, 32) + +VECT_TESTS(sc_, signed char, 16) +VECT_TESTS(ss_, short, 32) +VECT_TESTS(si_, int, 32) +VECT_TESTS(sl_, long, 32) + +int main () +{ + int i; + + check_vect (); + + uc_tests (); + us_tests (); + ui_tests (); + ul_tests (); + + sc_tests (); + ss_tests (); + si_tests (); + sl_tests (); + + TRACE_DONE (); + return 0; +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-mult.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-mult.c new file mode 100644 index 000000000..c88814297 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-mult.c @@ -0,0 +1,76 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; +} s; + +typedef struct { + unsigned int a; + unsigned int b; +} ii; + +__attribute__ ((noinline)) int +main1 () +{ + s arr[N]; + s *ptr = arr; + ii iarr[N]; + ii *iptr = iarr; + s res[N]; + ii ires[N]; + int i; + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + iarr[i].a = i; + iarr[i].b = i * 3; + if (arr[i].a == 178) + abort(); + } + + for (i = 0; i < N; i++) + { + ires[i].a = iptr->b - iptr->a; + ires[i].b = iptr->b + iptr->a; + res[i].b = ptr->b - ptr->a; + res[i].a = ptr->b + ptr->a; + iptr++; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].b != arr[i].b - arr[i].a + || ires[i].a != iarr[i].b - iarr[i].a + || res[i].a != arr[i].b + arr[i].a + || ires[i].b != iarr[i].b + iarr[i].a +) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-i2.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-i2.c new file mode 100644 index 000000000..702d911ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-i2.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; +} s; + +__attribute__ ((noinline)) int +main1 () +{ + s arr[N]; + s *ptr = arr; + s res[N]; + int i; + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + if (arr[i].a == 178) + abort(); + } + + for (i = 0; i < N; i++) + { + res[i].a = ptr->b - ptr->a; + res[i].b = ptr->b + ptr->a; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].b - arr[i].a + || res[i].b != arr[i].a + arr[i].b) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-i4.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-i4.c new file mode 100644 index 000000000..93c1b582c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-i4.c @@ -0,0 +1,73 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; + unsigned short c; + unsigned short d; +} s; + +__attribute__ ((noinline)) int +main1 () +{ + s arr[N]; + s *ptr = arr; + s res[N]; + int i; + unsigned short x, y, z, w; + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + if (arr[i].a == 178) + abort(); + } + + for (i = 0; i < N; i++) + { + x = ptr->b - ptr->a; + y = ptr->d - ptr->c; + res[i].c = x + y; + z = ptr->a + ptr->c; + w = ptr->b + ptr->d; + res[i].a = z + w; + res[i].d = x + y; + res[i].b = x + y; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].a != arr[i].a + arr[i].c + arr[i].b + arr[i].d + || res[i].d != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].b != arr[i].b - arr[i].a + arr[i].d - arr[i].c) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-mult.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-mult.c new file mode 100644 index 000000000..afb2f4697 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u16-mult.c @@ -0,0 +1,67 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; +} s; + +__attribute__ ((noinline)) int +main1 () +{ + s arr[N]; + s *ptr = arr; + unsigned int iarr[N]; + unsigned int *iptr = iarr; + s res[N]; + unsigned int ires[N]; + int i; + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + iarr[i] = i * 3; + if (arr[i].a == 178) + abort(); + } + + for (i = 0; i < N; i++) + { + ires[i] = *iptr; + res[i].b = ptr->b - ptr->a; + res[i].a = ptr->b + ptr->a; + iptr++; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].b != arr[i].b - arr[i].a + || ires[i] != iarr[i] + || res[i].a != arr[i].b + arr[i].a) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-u32-mult.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u32-mult.c new file mode 100644 index 000000000..bac1caa1c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u32-mult.c @@ -0,0 +1,66 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned int a; + unsigned int b; +} ii; + +__attribute__ ((noinline)) int +main1 () +{ + unsigned short arr[N]; + unsigned short *ptr = arr; + ii iarr[N]; + ii *iptr = iarr; + unsigned short res[N]; + ii ires[N]; + int i; + + for (i = 0; i < N; i++) + { + arr[i] = i; + iarr[i].a = i; + iarr[i].b = i * 3; + __asm__ volatile (""); + } + + for (i = 0; i < N; i++) + { + ires[i].a = iptr->b - iptr->a; + ires[i].b = iptr->b + iptr->a; + res[i] = *ptr; + iptr++; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i] != arr[i] + || ires[i].a != iarr[i].b - iarr[i].a + || ires[i].b != iarr[i].b + iarr[i].a) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i2-gap.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i2-gap.c new file mode 100644 index 000000000..cda573935 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i2-gap.c @@ -0,0 +1,74 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +typedef struct { + unsigned char a; + unsigned char b; +} s; + +__attribute__ ((noinline)) int +main1 () +{ + s arr[N]; + s *ptr = arr; + s res[N]; + int i; + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + if (arr[i].a == 178) + abort(); + } + + for (i = 0; i < N; i++) + { + res[i].a = ptr->a; + res[i].b = ptr->a; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].a + || res[i].b != arr[i].a) + abort (); + } + + ptr = arr; + /* Not vectorizable: gap in store. */ + for (i = 0; i < N; i++) + { + res[i].a = ptr->b; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].b) + abort (); + } + + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i8-gap2.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i8-gap2.c new file mode 100644 index 000000000..426069ffe --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i8-gap2.c @@ -0,0 +1,81 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} s; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + s arr[N]; + s *ptr = arr; + s res[N]; + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i + 5; + arr[i].f = i * 2 + 2; + arr[i].g = i - 3; + arr[i].h = 56; + if (arr[i].a == 178) + abort(); + } + + for (i = 0; i < N; i++) + { + res[i].c = ptr->a; + res[i].a = ptr->f + ptr->a; + res[i].d = ptr->f - ptr->a; + res[i].b = ptr->f; + res[i].f = ptr->a; + res[i].e = ptr->f - ptr->a; + res[i].h = ptr->f; + res[i].g = ptr->f - ptr->a; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].a + || res[i].a != arr[i].f + arr[i].a + || res[i].d != arr[i].f - arr[i].a + || res[i].b != arr[i].f + || res[i].f != arr[i].a + || res[i].e != arr[i].f - arr[i].a + || res[i].h != arr[i].f + || res[i].g != arr[i].f - arr[i].a) + abort(); + } +} + + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i8-gap7.c b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i8-gap7.c new file mode 100644 index 000000000..8dfb21be9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-a-u8-i8-gap7.c @@ -0,0 +1,86 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} s; + +__attribute__ ((noinline)) int +main1 () +{ + int i; + s arr[N]; + s *ptr = arr; + s res[N]; + unsigned char u, t, s, x, y, z, w; + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i * 3 + 5; + arr[i].f = i * 5; + arr[i].g = i - 3; + arr[i].h = 67; + if (arr[i].a == 178) + abort(); + } + + for (i = 0; i < N; i++) + { + u = ptr->b - ptr->a; + t = ptr->d - ptr->c; + res[i].c = u + t; + x = ptr->b + ptr->d; + res[i].a = ptr->a + x; + res[i].d = u + t; + s = ptr->h - ptr->a; + res[i].b = s + t; + res[i].f = ptr->f + ptr->h; + res[i].e = ptr->b + ptr->e; + res[i].h = ptr->d; + res[i].g = u + t; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].a != arr[i].a + arr[i].b + arr[i].d + || res[i].d != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].b != arr[i].h - arr[i].a + arr[i].d - arr[i].c + || res[i].f != arr[i].f + arr[i].h + || res[i].e != arr[i].b + arr[i].e + || res[i].h != arr[i].d + || res[i].g != arr[i].b - arr[i].a + arr[i].d - arr[i].c) + abort(); + } +} + + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-float.c b/gcc/testsuite/gcc.dg/vect/vect-strided-float.c new file mode 100644 index 000000000..38c50b9cd --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-float.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_float } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +float b[N*2] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93}; +float c[N*2] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31}; + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + float a[N*2]; + + /* Strided access pattern. */ + for (i = 0; i < N/2; i++) + { + a[i*2] = b[2*i+1] * c[2*i+1] - b[2*i] * c[2*i]; + a[i*2+1] = b[2*i+8] * c[2*i+9] + b[2*i+9] * c[2*i+8]; + } + + /* Check results. */ + for (i = 0; i < N/2; i++) + { + if (a[i*2] != b[2*i+1] * c[2*i+1] - b[2*i] * c[2*i] + || a[i*2+1] != b[2*i+8] * c[2*i+9] + b[2*i+9] * c[2*i+8]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* Needs interleaving support. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd_wide } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { xfail { vect_interleave && vect_extract_even_odd_wide } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-mult-char-ls.c b/gcc/testsuite/gcc.dg/vect/vect-strided-mult-char-ls.c new file mode 100644 index 000000000..3890a7968 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-mult-char-ls.c @@ -0,0 +1,76 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +typedef struct { + unsigned char a; + unsigned char b; +} s; + +typedef struct { + unsigned int a; + unsigned int b; +} ii; + +__attribute__ ((noinline)) int +main1 (s *arr, ii *iarr) +{ + s *ptr = arr; + ii *iptr = iarr; + s res[N]; + ii ires[N]; + int i; + + for (i = 0; i < N; i++) + { + ires[i].a = iptr->b; + ires[i].b = iptr->a; + res[i].b = ptr->b - ptr->a; + res[i].a = ptr->b + ptr->a; + iptr++; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].b != arr[i].b - arr[i].a + || ires[i].a != iarr[i].b + || res[i].a != arr[i].b + arr[i].a + || ires[i].b != iarr[i].a +) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + ii iarr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + iarr[i].a = i; + iarr[i].b = i * 3; + if (arr[i].a == 178) + abort(); + } + + main1 (arr, iarr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-mult.c b/gcc/testsuite/gcc.dg/vect/vect-strided-mult.c new file mode 100644 index 000000000..6ddf09324 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-mult.c @@ -0,0 +1,76 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; +} s; + +typedef struct { + unsigned int a; + unsigned int b; +} ii; + +__attribute__ ((noinline)) int +main1 (s *arr, ii *iarr) +{ + s *ptr = arr; + ii *iptr = iarr; + s res[N]; + ii ires[N]; + int i; + + for (i = 0; i < N; i++) + { + ires[i].a = iptr->b - iptr->a; + ires[i].b = iptr->b + iptr->a; + res[i].b = ptr->b - ptr->a; + res[i].a = ptr->b + ptr->a; + iptr++; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].b != arr[i].b - arr[i].a + || ires[i].a != iarr[i].b - iarr[i].a + || res[i].a != arr[i].b + arr[i].a + || ires[i].b != iarr[i].b + iarr[i].a +) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + ii iarr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + iarr[i].a = i; + iarr[i].b = i * 3; + if (arr[i].a == 178) + abort(); + } + + main1 (arr, iarr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c b/gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c new file mode 100644 index 000000000..5f18baab4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-same-dr.c @@ -0,0 +1,76 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; +} s; + +s buffer1[N], buffer2[N]; + +__attribute__ ((noinline)) int +main1 (s * __restrict__ pIn, s* __restrict__ pOut) +{ + unsigned short i, x, y, d; + s *p, *q; + + p = pIn; + q = pOut; + + for (i = 0; i < N/2; i++) + { + x = pIn->a + 5; + y = pIn->a + 2; + pOut->a = x; + pOut->b = pIn->b; + pOut++; + pOut->a = y; + pOut->b = pIn->b; + pOut++; + pIn++; + } + + /* check results: */ + for (i = 0; i < N/2; i++) + { + if (q->a != p->a + 5 + || q->b != p->b) + abort (); + q++; + if (q->a != p->a + 2 + || q->b != p->b) + abort (); + q++; + p++; + } + + return 0; +} + +int main (void) +{ + short i; + + for (i = 0; i < N; i++) + { + buffer1[i].a = i; + buffer1[i].b = i + 8; + buffer2[i].a = i * 3; + buffer2[i].b = i * 2; + if (buffer1[i].a == 500) + abort(); + } + + check_vect (); + + main1 (buffer1, buffer2); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-store-a-u8-i2.c b/gcc/testsuite/gcc.dg/vect/vect-strided-store-a-u8-i2.c new file mode 100644 index 000000000..8548d267e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-store-a-u8-i2.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +typedef struct { + unsigned char a; + unsigned char b; +} s; + +__attribute__ ((noinline)) int +main1 () +{ + s arr[N]; + s *ptr = arr; + s res[N]; + int i; + unsigned char a[N], b[N]; + + + for (i = 0; i < N; i++) + { + a[i] = i; + b[i] = i * 2; + if (i%3 == 0) + a[i] = 10; + } + + for (i = 0; i < N; i++) + { + res[i].a = a[i] + 3; + res[i].b = a[i] + b[i]; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != a[i] + 3 + || res[i].b != a[i] + b[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + main1 (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-store-u16-i4.c b/gcc/testsuite/gcc.dg/vect/vect-strided-store-u16-i4.c new file mode 100644 index 000000000..5c02c0da2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-store-u16-i4.c @@ -0,0 +1,72 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; + unsigned short c; + unsigned short d; +} s; + +unsigned short a[N]; +unsigned short b[N]; +unsigned short c[N]; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + unsigned short x, y, z, w; + + for (i = 0; i < N; i++) + { + res[i].c = a[i]; + res[i].a = b[i]; + res[i].d = c[i]; + res[i].b = a[i] + b [i]; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != a[i] + || res[i].a != b[i] + || res[i].d != c[i] + || res[i].b != a[i] + b[i]) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + a[i] = i; + b[i] = i * 2; + c[i] = 17; + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target { vect_interleave && vect_pack_trunc } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { { ! { vect_interleave } } && { vect_pack_trunc } } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-store-u32-i2.c b/gcc/testsuite/gcc.dg/vect/vect-strided-store-u32-i2.c new file mode 100644 index 000000000..c30c98d7e --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-store-u32-i2.c @@ -0,0 +1,45 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +int a[N*2]; +int b[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; +int c[N] = {1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31}; + +__attribute__ ((noinline)) int +main1 (void) +{ + int i; + + /* Strided access pattern. */ + for (i = 0; i < N/2; i++) + { + a[i*2] = b[i] + c[i]; + a[i*2+1] = b[i] * c[i]; + } + + /* Check results. */ + for (i = 0; i < N/2; i++) + { + if (a[i*2] != b[i] + c[i] + || a[i*2+1] != b[i] * c[i]) + abort(); + } + + return 0; +} + +int main (void) +{ + check_vect (); + return main1 (); +} + +/* Needs interleaving support. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { xfail { vect_interleave } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u16-i2.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u16-i2.c new file mode 100644 index 000000000..eb6ecc69b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u16-i2.c @@ -0,0 +1,60 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + s *ptr = arr; + s res[N]; + int i; + + for (i = 0; i < N; i++) + { + res[i].a = ptr->b - ptr->a; + res[i].b = ptr->b + ptr->a; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].b - arr[i].a + || res[i].b != arr[i].a + arr[i].b) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u16-i4.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u16-i4.c new file mode 100644 index 000000000..da5a72855 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u16-i4.c @@ -0,0 +1,73 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned short a; + unsigned short b; + unsigned short c; + unsigned short d; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + unsigned short x, y, z, w; + + for (i = 0; i < N; i++) + { + x = ptr->b - ptr->a; + y = ptr->d - ptr->c; + res[i].c = x + y; + z = ptr->a + ptr->c; + w = ptr->b + ptr->d; + res[i].a = z + w; + res[i].d = x + y; + res[i].b = x + y; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].a != arr[i].a + arr[i].c + arr[i].b + arr[i].d + || res[i].d != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].b != arr[i].b - arr[i].a + arr[i].d - arr[i].c) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u32-i4.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u32-i4.c new file mode 100644 index 000000000..96ee25442 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u32-i4.c @@ -0,0 +1,68 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + int a; + int b; + int c; + int d; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + + for (i = 0; i < N; i++) + { + res[i].c = ptr->b - ptr->a + ptr->d - ptr->c; + res[i].a = ptr->a + ptr->c + ptr->b + ptr->d; + res[i].d = ptr->b - ptr->a + ptr->d - ptr->c; + res[i].b = ptr->b - ptr->a + ptr->d - ptr->c; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].a != arr[i].a + arr[i].c + arr[i].b + arr[i].d + || res[i].d != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].b != arr[i].b - arr[i].a + arr[i].d - arr[i].c) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u32-i8.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u32-i8.c new file mode 100644 index 000000000..5f5a66e63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u32-i8.c @@ -0,0 +1,82 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + int a; + int b; + int c; + int d; + int e; + int f; + int g; + int h; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + + for (i = 0; i < N; i++) + { + res[i].c = ptr->b - ptr->a + ptr->d - ptr->c; + res[i].a = ptr->a + ptr->g + ptr->b + ptr->d; + res[i].d = ptr->b - ptr->a + ptr->d - ptr->c; + res[i].b = ptr->h - ptr->a + ptr->d - ptr->c; + res[i].f = ptr->f + ptr->h; + res[i].e = ptr->b - ptr->e; + res[i].h = ptr->d - ptr->g; + res[i].g = ptr->b - ptr->a + ptr->d - ptr->c; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].a != arr[i].a + arr[i].g + arr[i].b + arr[i].d + || res[i].d != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].b != arr[i].h - arr[i].a + arr[i].d - arr[i].c + || res[i].f != arr[i].f + arr[i].h + || res[i].e != arr[i].b - arr[i].e + || res[i].h != arr[i].d - arr[i].g + || res[i].g != arr[i].b - arr[i].a + arr[i].d - arr[i].c) + abort(); + } +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i * 3 + 5; + arr[i].f = i * 5; + arr[i].g = i - 3; + arr[i].h = 56; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u32-mult.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u32-mult.c new file mode 100644 index 000000000..f900b71f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u32-mult.c @@ -0,0 +1,65 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +typedef struct { + unsigned int a; + unsigned int b; +} ii; + +__attribute__ ((noinline)) int +main1 (unsigned short *arr, ii *iarr) +{ + unsigned short *ptr = arr; + ii *iptr = iarr; + unsigned short res[N]; + ii ires[N]; + int i; + + for (i = 0; i < N; i++) + { + ires[i].a = iptr->b - iptr->a; + ires[i].b = iptr->b + iptr->a; + res[i] = *ptr; + iptr++; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i] != arr[i] + || ires[i].a != iarr[i].b - iarr[i].a + || ires[i].b != iarr[i].b + iarr[i].a) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + unsigned short arr[N]; + ii iarr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i] = i; + iarr[i].a = i; + iarr[i].b = i * 3; + __asm__ volatile (""); + } + main1 (arr, iarr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2-gap.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2-gap.c new file mode 100644 index 000000000..b18b66058 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2-gap.c @@ -0,0 +1,76 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +typedef struct { + unsigned char a; + unsigned char b; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + s *ptr = arr; + s res[N]; + int i; + + for (i = 0; i < N; i++) + { + res[i].a = ptr->b; + res[i].b = ptr->b; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].b + || res[i].b != arr[i].b) + abort (); + } + + ptr = arr; + /* Not vectorizable: gap in store. */ + for (i = 0; i < N; i++) + { + res[i].a = ptr->b; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].b) + abort (); + } + + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2.c new file mode 100644 index 000000000..2f44b8e4a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i2.c @@ -0,0 +1,59 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +typedef struct { + unsigned char a; + unsigned char b; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + s *ptr = arr; + s res[N]; + int i; + + for (i = 0; i < N; i++) + { + res[i].a = ptr->b - ptr->a; + res[i].b = ptr->b + ptr->a; + ptr++; + } + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].b - arr[i].a + || res[i].b != arr[i].a + arr[i].b) + abort (); + } + + return 0; +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap2.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap2.c new file mode 100644 index 000000000..f5285361a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap2.c @@ -0,0 +1,83 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + + for (i = 0; i < N; i++) + { + res[i].c = ptr->b; + res[i].a = ptr->f + ptr->b; + res[i].d = ptr->f - ptr->b; + res[i].b = ptr->f; + res[i].f = ptr->b; + res[i].e = ptr->f - ptr->b; + res[i].h = ptr->f; + res[i].g = ptr->f - ptr->b; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b + || res[i].a != arr[i].f + arr[i].b + || res[i].d != arr[i].f - arr[i].b + || res[i].b != arr[i].f + || res[i].f != arr[i].b + || res[i].e != arr[i].f - arr[i].b + || res[i].h != arr[i].f + || res[i].g != arr[i].f - arr[i].b) + abort(); + } +} + + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i + 5; + arr[i].f = i * 2 + 2; + arr[i].g = i - 3; + arr[i].h = 56; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap4-unknown.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap4-unknown.c new file mode 100644 index 000000000..ccbc366f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap4-unknown.c @@ -0,0 +1,116 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include <stdio.h> +#include "tree-vect.h" + +#define N 160 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr, int n) +{ + int i; + s *ptr = arr; + s res[N]; + unsigned char x; + + for (i = 0; i < N; i++) + { + res[i].a = 0; + res[i].b = 0; + res[i].c = 0; + res[i].d = 0; + res[i].e = 0; + res[i].f = 0; + res[i].g = 0; + res[i].h = 0; + __asm__ volatile (""); + } + + /* Check peeling for gaps for unknown loop bound. */ + for (i = 0; i < n; i++) + { + res[i].c = ptr->b + ptr->c; + x = ptr->c + ptr->f; + res[i].a = x + ptr->b; + res[i].d = ptr->b + ptr->c; + res[i].b = ptr->c; + res[i].f = ptr->f + ptr->e; + res[i].e = ptr->b + ptr->e; + res[i].h = ptr->c; + res[i].g = ptr->b + ptr->c; + ptr++; + } + + /* check results: */ + for (i = 0; i < n; i++) + { + if (res[i].c != arr[i].b + arr[i].c + || res[i].a != arr[i].c + arr[i].f + arr[i].b + || res[i].d != arr[i].b + arr[i].c + || res[i].b != arr[i].c + || res[i].f != arr[i].f + arr[i].e + || res[i].e != arr[i].b + arr[i].e + || res[i].h != arr[i].c + || res[i].g != arr[i].b + arr[i].c) + abort (); + } + + /* Check also that we don't do more iterations than needed. */ + for (i = n; i < N; i++) + { + if (res[i].c == arr[i].b + arr[i].c + || res[i].a == arr[i].c + arr[i].f + arr[i].b + || res[i].d == arr[i].b + arr[i].c + || res[i].b == arr[i].c + || res[i].f == arr[i].f + arr[i].e + || res[i].e == arr[i].b + arr[i].e + || res[i].h == arr[i].c + || res[i].g == arr[i].b + arr[i].c) + abort (); + } + + return 0; +} + + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = 5; + arr[i].b = 6; + arr[i].c = 17; + arr[i].d = 3; + arr[i].e = 16; + arr[i].f = 16; + arr[i].g = 3; + arr[i].h = 56; + if (arr[i].a == 178) + abort(); + } + + main1 (arr, N-2); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap4.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap4.c new file mode 100644 index 000000000..1bd932b8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap4.c @@ -0,0 +1,103 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + unsigned char x; + + for (i = 0; i < N; i++) + { + res[i].c = ptr->b + ptr->c; + x = ptr->c + ptr->f; + res[i].a = x + ptr->b; + res[i].d = ptr->b + ptr->c; + res[i].b = ptr->c; + res[i].f = ptr->f + ptr->e; + res[i].e = ptr->b + ptr->e; + res[i].h = ptr->c; + res[i].g = ptr->b + ptr->c; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b + arr[i].c + || res[i].a != arr[i].c + arr[i].f + arr[i].b + || res[i].d != arr[i].b + arr[i].c + || res[i].b != arr[i].c + || res[i].f != arr[i].f + arr[i].e + || res[i].e != arr[i].b + arr[i].e + || res[i].h != arr[i].c + || res[i].g != arr[i].b + arr[i].c) + abort (); + } + + ptr = arr; + /* Not vectorizable: gap in store. */ + for (i = 0; i < N; i++) + { + res[i].a = ptr->b; + res[i].b = ptr->c; + ptr++; + } + + /* Check results. */ + for (i = 0; i < N; i++) + { + if (res[i].a != arr[i].b + || res[i].b != arr[i].c) + abort (); + } + +} + + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i * 3 + 5; + arr[i].f = i * 5; + arr[i].g = i - 3; + arr[i].h = 56; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap7.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap7.c new file mode 100644 index 000000000..be8ef671a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8-gap7.c @@ -0,0 +1,88 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + unsigned char u, t, s, x, y, z, w; + + for (i = 0; i < N; i++) + { + u = ptr->b - ptr->a; + t = ptr->d - ptr->c; + res[i].c = u + t; + x = ptr->b + ptr->d; + res[i].a = ptr->a + x; + res[i].d = u + t; + s = ptr->h - ptr->a; + res[i].b = s + t; + res[i].f = ptr->f + ptr->h; + res[i].e = ptr->b + ptr->e; + res[i].h = ptr->d; + res[i].g = u + t; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].a != arr[i].a + arr[i].b + arr[i].d + || res[i].d != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].b != arr[i].h - arr[i].a + arr[i].d - arr[i].c + || res[i].f != arr[i].f + arr[i].h + || res[i].e != arr[i].b + arr[i].e + || res[i].h != arr[i].d + || res[i].g != arr[i].b - arr[i].a + arr[i].d - arr[i].c) + abort(); + } +} + + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i * 3 + 5; + arr[i].f = i * 5; + arr[i].g = i - 3; + arr[i].h = 67; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8.c b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8.c new file mode 100644 index 000000000..ff5171d92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-strided-u8-i8.c @@ -0,0 +1,90 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 32 + +typedef struct { + unsigned char a; + unsigned char b; + unsigned char c; + unsigned char d; + unsigned char e; + unsigned char f; + unsigned char g; + unsigned char h; +} s; + +__attribute__ ((noinline)) int +main1 (s *arr) +{ + int i; + s *ptr = arr; + s res[N]; + unsigned char u, t, s, x, y, z, w; + + for (i = 0; i < N; i++) + { + u = ptr->b - ptr->a; + t = ptr->d - ptr->c; + res[i].c = u + t; + s = ptr->a + ptr->g; + x = ptr->b + ptr->d; + res[i].a = s + x; + res[i].d = u + t; + s = ptr->h - ptr->a; + x = ptr->d - ptr->c; + res[i].b = s + x; + res[i].f = ptr->f + ptr->h; + res[i].e = ptr->b + ptr->e; + res[i].h = ptr->d - ptr->g; + res[i].g = u + t; + ptr++; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (res[i].c != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].a != arr[i].a + arr[i].g + arr[i].b + arr[i].d + || res[i].d != arr[i].b - arr[i].a + arr[i].d - arr[i].c + || res[i].b != arr[i].h - arr[i].a + arr[i].d - arr[i].c + || res[i].f != arr[i].f + arr[i].h + || res[i].e != arr[i].b + arr[i].e + || res[i].h != arr[i].d - arr[i].g + || res[i].g != arr[i].b - arr[i].a + arr[i].d - arr[i].c + ) + abort(); + } +} + +int main (void) +{ + int i; + s arr[N]; + + check_vect (); + + for (i = 0; i < N; i++) + { + arr[i].a = i; + arr[i].b = i * 2; + arr[i].c = 17; + arr[i].d = i+34; + arr[i].e = i; + arr[i].f = i + 5; + arr[i].g = i + 3; + arr[i].h = 67; + if (arr[i].a == 178) + abort(); + } + + main1 (arr); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-01.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-01.c new file mode 100644 index 000000000..4ae967a19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-01.c @@ -0,0 +1,39 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +int result[N] = {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}; +int X[N] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}; +int Y[N] = {}; + +__attribute__ ((noinline)) void +foo (int *in, int *out) +{ + int i; + + for (i = 0; i < N; i++) + out[i] = in[i] + 2; +} + +int +main (void) +{ + int i; + + check_vect (); + + foo (X, Y); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (Y[i] != result[i]) + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-02.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-02.c new file mode 100644 index 000000000..13ab54a98 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-02.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +int resultY[N] = {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27}; +int resultZ[N] = {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28}; +int X[N] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}; +int Y[N] = {}; +int Z[N] = {}; + +__attribute__ ((noinline)) void +foo (int *in, int *out1, int *out2) +{ + int i; + + for (i = 0; i < N; i++) + { + out1[i] = in[i] + 2; + out2[i] = in[i] + 3; + } +} + +int +main (void) +{ + int i; + + check_vect (); + + foo (X, Y, Z); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (Y[i] != resultY[i]) + abort (); + + if (Z[i] != resultZ[i]) + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-03.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-03.c new file mode 100644 index 000000000..7d684aa1f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-03.c @@ -0,0 +1,58 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +struct S +{ + unsigned short a; + unsigned short b; +}; + +struct S result[N] = {20, 13, 22, 14, 24, 15, 26, 16, 28, 17, 30, 18, + 32, 19, 34, 20, 36, 21, 38, 22, 40, 23, 42, 24, + 44, 25, 46, 26, 48, 27, 50, 28}; +struct S X[N] = {10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, + 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25}; +struct S Y[N] = {}; + +__attribute__ ((noinline)) void +foo (struct S * in, struct S * out) +{ + int i; + + for (i = 0; i < N; i++) + { + out[i].a = in[i].a * 2; + out[i].b = in[i].b + 3; + } +} + +int +main (void) +{ + int i; + + check_vect (); + + foo (X, Y); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (Y[i].a != result[i].a) + abort (); + + if (Y[i].b != result[i].b) + abort (); + + } + return 0; +} + +/* Needs interleaving support. */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { xfail { vect_interleave && vect_extract_even_odd } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-04.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-04.c new file mode 100644 index 000000000..bbe2996af --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-04.c @@ -0,0 +1,38 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +int result[] = {10, 11, 15, 16, 20, 21, 25, 26, 30, 31, 35, 36, 40, 41, 45, 46, 50, 51}; +int X[] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0}; + +__attribute__ ((noinline)) void +foo (int *in, int *out) +{ + int i; + + for (i = 0; i < N; i++) + out[i] = in[i] + 5; +} + +int +main (void) +{ + int i; + + check_vect (); + + foo (X, &X[2]); + + /* check results: */ + for (i = 0; i < N+2; i++) + { + if (X[i] != result[i]) + abort (); + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-vfa-slp.c b/gcc/testsuite/gcc.dg/vect/vect-vfa-slp.c new file mode 100644 index 000000000..f53985d3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-vfa-slp.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +struct S +{ + unsigned short a; + unsigned short b; +}; + +struct S result[N] = {12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, + 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, + 24, 25, 25, 26, 26, 27, 27, 28}; +struct S X[N] = {10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, + 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25}; +struct S Y[N] = {}; + +__attribute__ ((noinline)) void +foo (struct S * in, struct S * out) +{ + int i; + + for (i = 0; i < N; i++) + { + out[i].a = in[i].a + 2; + out[i].b = in[i].b + 3; + } +} + +int +main (void) +{ + int i; + + check_vect (); + + foo (X, Y); + + /* check results: */ + for (i = 0; i < N; i++) + { + if (Y[i].a != result[i].a) + abort (); + + if (Y[i].b != result[i].b) + abort (); + + } + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-widen-mult-s16.c b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-s16.c new file mode 100644 index 000000000..983d7e70c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-s16.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +int result[N]; + +/* short->int widening-mult */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + result[i] = X[i] * Y[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (result[i] != X[i] * Y[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-widen-mult-s8.c b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-s8.c new file mode 100644 index 000000000..7a4c3c008 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-s8.c @@ -0,0 +1,46 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +signed char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +short result[N]; + +/* char->short widening-mult */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + result[i] = X[i] * Y[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (result[i] != X[i] * Y[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_qi_to_hi } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-widen-mult-sum.c b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-sum.c new file mode 100644 index 000000000..289891830 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-sum.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 +#define SUM 0 + +/* Require widening-mult or data-unpacking (for the type promotion). */ +__attribute__ ((noinline)) int +main1 (short *in, int off, short scale, int n) +{ + int i; + int sum = 0; + + for (i = 0; i < n; i++) { + sum += ((int) in[i] * (int) in[i+off]) >> scale; + } + + return sum; +} + +int main (void) +{ + int i; + int sum; + short X[N]; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = 16-i; + __asm__ volatile (""); + } + + sum = main1 (X, 1, 16, N-1); + + if (sum != SUM) + abort (); + + return 0; +} + + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_mult_hi_to_si } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-widen-mult-u16.c b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-u16.c new file mode 100644 index 000000000..92d2e85a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-u16.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned int result[N]; + +/* short->int widening-mult */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + /* Not vectorized because X[i] and Y[i] are casted to 'int' + so the widening multiplication pattern is not recognized. */ + for (i=0; i<len; i++) { + result[i] = (unsigned int)(X[i] * Y[i]); + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + __asm__ volatile (""); + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (result[i] != X[i] * Y[i]) + abort (); + } + + return 0; +} + +/*The induction loop is vectorized */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect-widen-mult-u8.c b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-u8.c new file mode 100644 index 000000000..1658f7b5a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-widen-mult-u8.c @@ -0,0 +1,47 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +unsigned char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); +unsigned short result[N]; + +/* char->short widening-mult */ +__attribute__ ((noinline)) int +foo1(int len) { + int i; + + for (i=0; i<len; i++) { + result[i] = X[i] * Y[i]; + } +} + +int main (void) +{ + int i; + + check_vect (); + + for (i=0; i<N; i++) { + X[i] = i; + Y[i] = 64-i; + if (i%4 == 0) + X[i] = 5; + } + + foo1 (N); + + for (i=0; i<N; i++) { + if (result[i] != X[i] * Y[i]) + abort (); + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_qi_to_hi || vect_unpack } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp new file mode 100644 index 000000000..170c33db2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect.exp @@ -0,0 +1,241 @@ +# Copyright (C) 1997, 2004, 2005, 2006, 2007, 2008, 2010 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# <http://www.gnu.org/licenses/>. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# Set up flags used for tests that don't specify options. +global DEFAULT_VECTCFLAGS +set DEFAULT_VECTCFLAGS "" + +# If the target system supports vector instructions, the default action +# for a test is 'run', otherwise it's 'compile'. Save current default. +# Executing vector instructions on a system without hardware vector support +# is also disabled by a call to check_vect, but disabling execution here is +# more efficient. +global dg-do-what-default +set save-dg-do-what-default ${dg-do-what-default} + +# Skip these tests for targets that do not support generating vector +# code. Set additional target-dependent vector flags, which can be +# overridden by using dg-options in individual tests. +if ![check_vect_support_and_set_flags] { + return +} + +global VEC_FLAGS +set VEC_FLAGS $DEFAULT_VECTCFLAGS + +# These flags are used for all targets. +lappend DEFAULT_VECTCFLAGS "-ftree-vectorize" "-fno-vect-cost-model" + +# Initialize `dg'. +dg-init + +global O1_VECTCFLAGS +set O1_VECTCFLAGS $DEFAULT_VECTCFLAGS +lappend O1_VECTCFLAGS "-O1" +lappend O1_VECTCFLAGS "-fdump-tree-vect-details" + +global O_VECTCFLAGS +set O_VECTCFLAGS $DEFAULT_VECTCFLAGS +lappend O_VECTCFLAGS "-O" +lappend O_VECTCFLAGS "-fdump-tree-vect-details" + +lappend DEFAULT_VECTCFLAGS "-O2" + +# Tests that should be run without generating dump info +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/nodump-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# "-O -fdump-tree-veclower" +lappend VEC_FLAGS "-O" "-fdump-tree-veclower" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vec-scal-*.\[cS\]]] \ + "" $VEC_FLAGS + +set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS + +lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details" +lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details" + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pr*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/slp-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/bb-slp*.\[cS\]]] \ + "" $VECT_SLP_CFLAGS + + +#### Tests with special options +global SAVED_DEFAULT_VECTCFLAGS +set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS +set SAVED_VECT_SLP_CFLAGS $VECT_SLP_CFLAGS + +# --param vect-max-version-for-alias-checks=0 tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "--param" "vect-max-version-for-alias-checks=0" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-vfa-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -ffast-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ffast-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/fast-math-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-math-errno tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-math-errno" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-math-errno-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fwrapv tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fwrapv" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/wrapv-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -ftrapv tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-ftrapv" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/trapv-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fdump-tree-dceloop-details tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fdump-tree-dceloop-details" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dump-tree-dceloop-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-dce tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-dce" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-tree-dce-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fsection-anchors tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fsection-anchors" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/section-anchors-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# alignment-sensitive -fsection-anchors tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fsection-anchors" "-fdump-ipa-increase_alignment" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/aligned-section-anchors-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-section-anchors tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-section-anchors" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-section-anchors-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -funswitch-loops tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-funswitch-loops" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/unswitch-loops-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-trapping-math tests +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-trapping-math" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-trapping-math-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-outer-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop -fno-tree-reassoc +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" "-fno-tree-reassoc" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-noreassoc-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-scev-cprop +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-scev-cprop" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-scevccp-slp-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-dominator-opts +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-dominator-opts" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-tree-dom-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# -fno-tree-pre +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-fno-tree-pre" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-tree-pre-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With -Os +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-Os" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/Os-vect-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With --param ggc-min-expand=0 --param ggc-min-heapsize=0 +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "--param" "ggc-min-expand=0" "--param" "ggc-min-heapsize=0" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/ggc-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With -O3. +# Don't allow IPA cloning, because it throws our counts out of whack. +set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS +lappend DEFAULT_VECTCFLAGS "-O3" "-fno-ipa-cp-clone" +if [istarget "spu-*-*"] { + lappend DEFAULT_VECTCFLAGS "-funroll-loops" +} +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/O3-*.\[cS\]]] \ + "" $DEFAULT_VECTCFLAGS + +# With -O1 +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/O1-*.\[cS\]]] \ + "" $O1_VECTCFLAGS + +# With -O +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/O-*.\[cS\]]] \ + "" $O_VECTCFLAGS + +# -fno-tree-reassoc +set VECT_SLP_CFLAGS $SAVED_VECT_SLP_CFLAGS +lappend VECT_SLP_CFLAGS "-fno-tree-reassoc" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-tree-reassoc-bb-slp-*.\[cS\]]] \ + "" $VECT_SLP_CFLAGS + +# Clean up. +set dg-do-what-default ${save-dg-do-what-default} + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/vect/wrapv-vect-7.c b/gcc/testsuite/gcc.dg/vect/wrapv-vect-7.c new file mode 100644 index 000000000..5d495440f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/wrapv-vect-7.c @@ -0,0 +1,52 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 128 + +short sa[N]; +short sb[N]; + +int main1 () +{ + int i; + + for (i = 0; i < N; i++) + { + sb[i] = 5; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (sb[i] != 5) + abort (); + } + + for (i = 0; i < N; i++) + { + sa[i] = sb[i] + (short)100; + } + + /* check results: */ + for (i = 0; i < N; i++) + { + if (sa[i] != 105) + abort (); + } + + return 0; +} + +int main (void) +{ + check_vect (); + + return main1 (); +} + +/* Fails for 32-bit targets that don't vectorize PLUS. */ +/* { 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 { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-2char.c b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-2char.c new file mode 100644 index 000000000..4b04a9d41 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-2char.c @@ -0,0 +1,51 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 121 + +signed char b[N] = {1,2,3,6,8,10,12,14,16,18,20,22,24,26,28,30}; +signed char c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) +void main1 (signed char x, signed char max_result, signed char min_result) +{ + int i; + signed char diff = 2; + signed char max = x; + signed char min = x; + + for (i = 0; i < N; i++) { + diff += (signed char)(b[i] - c[i]); + } + + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-2short.c b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-2short.c new file mode 100644 index 000000000..0468b1966 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-2short.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +#define DIFF 242 + +short b[N] = {1,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45}; +short c[N] = {1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; + +__attribute__ ((noinline)) +void main1 (short x, short max_result, short min_result) +{ + int i; + short diff = 2; + short max = x; + short min = x; + + for (i = 0; i < N; i++) { + diff += (short)(b[i] - c[i]); + } + for (i = 0; i < N; i++) { + max = max < c[i] ? c[i] : max; + } + + for (i = 0; i < N; i++) { + min = min > c[i] ? c[i] : min; + } + + /* check results: */ + if (diff != DIFF) + abort (); + if (max != max_result) + abort (); + if (min != min_result) + abort (); +} + +int main (void) +{ + check_vect (); + + main1 (100, 100, 1); + main1 (0, 15, 0); + return 0; +} + +/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_int_max } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-dot-s8b.c b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-dot-s8b.c new file mode 100644 index 000000000..68caa8bd1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-dot-s8b.c @@ -0,0 +1,57 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 64 + +#define DOT -21856 + +signed char X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; +signed char Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1}; + +/* char->short->short dot product. + The dot-product pattern should be detected. + Should be vectorized on vect_sdot_qi targets (targets that support + dot-product of signed char). + This test currently fails to vectorize on targets that support + dot-product of chars into and int accumulator. + Can also be vectorized as widening-mult + summation, + or with type-conversion support. + */ +__attribute__ ((noinline)) short +foo(int len) { + int i; + short result = 0; + + for (i=0; i<len; i++) { + result += (X[i] * Y[i]); + } + return result; +} + +int main (void) +{ + int i; + short dot; + + check_vect (); + + dot = foo (N); + if (dot != DOT) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 1 "vect" } } */ + +/* When vectorizer is enhanced to vectorize accumulation into short for targets + that support accumulation into int (e.g. ia64) we'd have: +dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_sdot_qi } } +*/ +/* In the meantime expect: */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_widen_mult_qi_to_hi || vect_unpack } } } } */ + +/* { dg-final { cleanup-tree-dump "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-pattern-2c.c b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-pattern-2c.c new file mode 100644 index 000000000..12f365078 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/wrapv-vect-reduc-pattern-2c.c @@ -0,0 +1,41 @@ +/* { dg-require-effective-target vect_int } */ + +#include <stdarg.h> +#include "tree-vect.h" + +#define N 16 +signed char data_ch[N] = + { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28 }; +#define SUM 210 + +__attribute__ ((noinline)) int +foo () +{ + int i; + signed short shortsum = 0; + + /* widenning sum: sum chars into short. */ + + for (i = 0; i < N; i++) + { + shortsum += data_ch[i]; + } + + /* check results: */ + if (shortsum != SUM) + abort (); + + return 0; +} + +int +main (void) +{ + check_vect (); + return foo (); +} + +/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_sum_qi_to_hi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_widen_sum_qi_to_hi } } } } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ |