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 void abort (); 7int a[32][32] __attribute__((aligned (32))) = { { 1 } }; 8struct S { int s; }; 9#pragma omp declare reduction (+:struct S:omp_out.s += omp_in.s) 10#pragma omp declare reduction (foo:struct S:omp_out.s += omp_in.s) 11#pragma omp declare reduction (foo:int:omp_out += omp_in) 12 13__attribute__((noinline, noclone)) int 14foo (void) 15{ 16 int i, j, u = 0; 17 struct S s, t; 18 s.s = 0; t.s = 0; 19 #pragma omp simd aligned(a : 32) lastprivate (i, j) reduction(+:s) reduction(foo:t, u) collapse(2) 20 for (i = 0; i < 32; i++) 21 for (j = 0; j < 32; j++) 22 { 23 int *q = &i; 24 int *r = &j; 25 int x = a[i][j]; 26 s.s += x; 27 t.s += x; 28 u += x; 29 } 30 if (t.s != s.s || u != s.s || i != 32 || j != 32) 31 abort (); 32 return s.s; 33} 34 35__attribute__((noinline, noclone)) int 36bar (void) 37{ 38 int i, j, u = 0; 39 struct S s, t; 40 s.s = 0; t.s = 0; 41 #pragma omp simd aligned(a:32)reduction(+:s)reduction(foo:t,u)collapse(2) 42 for (i = 0; i < 32; i++) 43 for (j = 0; j < 32; j++) 44 { 45 int *q = &i; 46 int *r = &j; 47 int x = a[i][j]; 48 s.s += x; 49 t.s += x; 50 u += x; 51 } 52 if (t.s != s.s || u != s.s || i != 32 || j != 32) 53 abort (); 54 return s.s; 55} 56 57int 58main () 59{ 60 int i, j; 61 for (i = 0; i < 32; i++) 62 for (j = 0; j < 32; j++) 63 a[i][j] = j + (i / 4); 64 int s = foo (); 65 if (s != 19456) 66 abort (); 67 if (bar () != 19456) 68 abort (); 69 return 0; 70} 71