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