1/* { dg-do run } */
2/* { dg-options "-O2" } */
3/* { dg-additional-options "-msse2" { target sse2_runtime } } */
4/* { dg-additional-options "-mavx" { target avx_runtime } } */
5
6extern void abort ();
7int a[1024] __attribute__((aligned (32))) = { 1 };
8int b[1024] __attribute__((aligned (32))) = { 1 };
9unsigned char c[1024] __attribute__((aligned (32))) = { 1 };
10int k, m;
11__UINTPTR_TYPE__ u, u2, u3;
12
13__attribute__((noinline, noclone)) int
14foo (int *p)
15{
16  int i, s = 0, s2 = 0, t, t2;
17  #pragma omp simd aligned(a, b, p : 32) linear(k: m + 1) reduction(+:s) \
18		   lastprivate (t2)
19  for (i = 0; i < 512; i++)
20    {
21      a[i] *= p[i];
22      t2 = k + p[i];
23      k += m + 1;
24      s += p[i] + k;
25      c[i]++;
26    }
27  #pragma omp simd aligned(a, b, p : 32) linear(k: m + 1) reduction(+:s2) \
28		   lastprivate (t, u, u2, u3)
29  for (i = 512; i < 1024; i++)
30    {
31      a[i] *= p[i];
32      k += m + 1;
33      t = k + p[i];
34      u = (__UINTPTR_TYPE__) &k;
35      u2 = (__UINTPTR_TYPE__) &s2;
36      u3 = (__UINTPTR_TYPE__) &t;
37      s2 += t;
38      c[i]++;
39    }
40  return s + s2 + t + t2;
41}
42
43__attribute__((noinline, noclone)) long int
44bar (int *p, long int n, long int o)
45{
46  long int i, s = 0, s2 = 0, t, t2;
47  #pragma omp simd aligned(a, b, p : 32) linear(k: m + 1) reduction(+:s) \
48		   lastprivate (t2)
49  for (i = 0; i < n; i++)
50    {
51      a[i] *= p[i];
52      t2 = k + p[i];
53      k += m + 1;
54      s += p[i] + k;
55      c[i]++;
56    }
57  #pragma omp simd aligned(a, b, p : 32) linear(k: m + 1) reduction(+:s2) \
58		   lastprivate (t, u, u2, u3)
59  for (i = n; i < o; i++)
60    {
61      a[i] *= p[i];
62      k += m + 1;
63      t = k + p[i];
64      u = (__UINTPTR_TYPE__) &k;
65      u2 = (__UINTPTR_TYPE__) &s2;
66      u3 = (__UINTPTR_TYPE__) &t;
67      s2 += t;
68      c[i]++;
69    }
70  return s + s2 + t + t2;
71}
72
73int
74main ()
75{
76#if __SIZEOF_INT__ >= 4
77  int i;
78  k = 4;
79  m = 2;
80  for (i = 0; i < 1024; i++)
81    {
82      a[i] = i - 512;
83      b[i] = (i - 51) % 39;
84      c[i] = (unsigned char) i;
85    }
86  int s = foo (b);
87  for (i = 0; i < 1024; i++)
88    {
89      if (b[i] != (i - 51) % 39
90	  || a[i] != (i - 512) * b[i]
91	  || c[i] != (unsigned char) (i + 1))
92	abort ();
93      a[i] = i - 512;
94    }
95  if (k != 4 + 3 * 1024
96      || s != 1596127 + (4 + 3 * 511 + b[511]) + (4 + 3 * 1024 + b[1023]))
97    abort ();
98  k = 4;
99  s = bar (b, 512, 1024);
100  for (i = 0; i < 1024; i++)
101    {
102      if (b[i] != (i - 51) % 39
103	  || a[i] != (i - 512) * b[i]
104	  || c[i] != (unsigned char) (i + 2))
105	abort ();
106      a[i] = i - 512;
107    }
108  if (k != 4 + 3 * 1024
109      || s != 1596127 + (4 + 3 * 511 + b[511]) + (4 + 3 * 1024 + b[1023]))
110    abort ();
111  k = 4;
112  s = bar (b, 511, 1021);
113  for (i = 0; i < 1021; i++)
114    {
115      if (b[i] != (i - 51) % 39
116	  || a[i] != (i - 512) * b[i]
117	  || c[i] != (unsigned char) (i + 3))
118	abort ();
119      a[i] = i - 512;
120    }
121  for (i = 1021; i < 1024; i++)
122    if (b[i] != (i - 51) % 39
123	|| a[i] != i - 512
124	|| c[i] != (unsigned char) (i + 2))
125      abort ();
126  if (k != 4 + 3 * 1021
127      || s != 1586803 + (4 + 3 * 510 + b[510]) + (4 + 3 * 1021 + b[1020]))
128    abort ();
129#endif
130  return 0;
131}
132