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 (int x) : s (x) {} 13 ~S () {} 14}; 15#pragma omp declare reduction (+:S:omp_out.s += omp_in.s) \ 16 initializer (omp_priv (0)) 17#pragma omp declare reduction (foo:S:omp_out.s += omp_in.s) \ 18 initializer (omp_priv (0)) 19#pragma omp declare reduction (foo:int:omp_out += omp_in) \ 20 initializer (omp_priv = 0) 21 22__attribute__((noinline, noclone)) S 23foo (S s) 24{ 25 int i, v = 0, &u = v; 26 S t; 27 #pragma omp simd aligned(a : 32) reduction(+:s) reduction(foo:t, u) 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 41bar (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 for (i = 0; i < 1024; i++) 46 { 47 int x = a[i]; 48 s.s += x; 49 t.s += x; 50 u += x; 51 } 52 if (t.s != s.s || u != s.s) 53 abort (); 54 return s.s; 55} 56 57int 58main () 59{ 60 int i; 61 for (i = 0; i < 1024; i++) 62 a[i] = (i & 31) + (i / 128); 63 S q; 64 int s = foo (q).s; 65 if (s != 19456) 66 abort (); 67 S r, v; 68 if (bar (r, v) != s) 69 abort (); 70} 71