1 // { dg-do run }
2 // { dg-additional-options "-msse2" { target sse2_runtime } }
3 // { dg-additional-options "-mavx" { target avx_runtime } }
4 
5 extern "C" void abort ();
6 int a[1024] __attribute__((aligned (32))) = { 1 };
7 struct S
8 {
9   int s;
SS10   S () : s (0) {}
SS11   S (int x) : s (x) {}
~SS12   ~S () {}
13 };
14 #pragma omp declare reduction (+:S:omp_out.s += omp_in.s) \
15 		    initializer (omp_priv (0))
16 #pragma omp declare reduction (foo:S:omp_out.s += omp_in.s) \
17 		    initializer (omp_priv (0))
18 #pragma omp declare reduction (foo:int:omp_out += omp_in) \
19 		    initializer (omp_priv = 0)
20 
21 __attribute__((noinline, noclone)) S
foo(S s)22 foo (S s)
23 {
24   int i, v = 0, &u = v;
25   S t;
26   #pragma omp simd aligned(a : 32) reduction(+:s) reduction(foo:t, u) \
27 		   safelen(1)
28   for (i = 0; i < 1024; i++)
29     {
30       int x = a[i];
31       s.s += x;
32       t.s += x;
33       u += x;
34     }
35   if (t.s != s.s || u != s.s)
36     abort ();
37   return t;
38 }
39 
40 __attribute__((noinline, noclone)) int
bar(S & s,S & t)41 bar (S &s, S &t)
42 {
43   int i, v = 0, &u = v;
44   #pragma omp simd aligned(a : 32) reduction(+:s) reduction(foo:t, u) \
45 		   safelen(1)
46   for (i = 0; i < 1024; i++)
47     {
48       int x = a[i];
49       s.s += x;
50       t.s += x;
51       u += x;
52     }
53   if (t.s != s.s || u != s.s)
54     abort ();
55   return s.s;
56 }
57 
58 int
main()59 main ()
60 {
61   int i;
62   for (i = 0; i < 1024; i++)
63     a[i] = (i & 31) + (i / 128);
64   S q;
65   int s = foo (q).s;
66   if (s != 19456)
67     abort ();
68   S r, v;
69   if (bar (r, v) != s)
70     abort ();
71 }
72