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   for (i = 0; i < 1024; i++)
28     {
29       int x = a[i];
30       s.s += x;
31       t.s += x;
32       u += x;
33     }
34   if (t.s != s.s || u != s.s)
35     abort ();
36   return t;
37 }
38 
39 __attribute__((noinline, noclone)) int
bar(S & s,S & t)40 bar (S &s, S &t)
41 {
42   int i, v = 0, &u = v;
43   #pragma omp simd aligned(a : 32) reduction(+:s) reduction(foo:t, u)
44   for (i = 0; i < 1024; i++)
45     {
46       int x = a[i];
47       s.s += x;
48       t.s += x;
49       u += x;
50     }
51   if (t.s != s.s || u != s.s)
52     abort ();
53   return s.s;
54 }
55 
56 int
main()57 main ()
58 {
59   int i;
60   for (i = 0; i < 1024; i++)
61     a[i] = (i & 31) + (i / 128);
62   S q;
63   int s = foo (q).s;
64   if (s != 19456)
65     abort ();
66   S r, v;
67   if (bar (r, v) != s)
68     abort ();
69 }
70