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 "C" void abort ();
7int a[1024] __attribute__((aligned (32))) = { 1 };
8struct S
9{
10  int s;
11  S () : s (0) {}
12  ~S () {}
13};
14#pragma omp declare reduction (+:S:omp_out.s += omp_in.s)
15#pragma omp declare reduction (foo:S:omp_out.s += omp_in.s)
16#pragma omp declare reduction (foo:int:omp_out += omp_in)
17
18__attribute__((noinline, noclone)) int
19foo ()
20{
21  int i, u = 0, q = 0;
22  S s, t;
23  #pragma omp simd aligned(a : 32) reduction(+:s, q) reduction(foo:t, u) \
24	      safelen(1)
25  for (i = 0; i < 1024; i++)
26    {
27      int x = a[i];
28      s.s += x;
29      t.s += x;
30      u += x;
31      q++;
32    }
33  if (t.s != s.s || u != s.s || q != 1024)
34    abort ();
35  return s.s;
36}
37
38int
39main ()
40{
41  int i;
42  for (i = 0; i < 1024; i++)
43    a[i] = (i & 31) + (i / 128);
44  int s = foo ();
45  if (s != 19456)
46    abort ();
47}
48