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