1 /* { dg-do run } */
2 /* { dg-options "-O2" } */
3 /* { dg-additional-options "-std=c99" { target c } } */
4 /* { dg-additional-options "-msse2" { target sse2_runtime } } */
5 /* { dg-additional-options "-mavx" { target avx_runtime } } */
6
7 #include <omp.h>
8 #include <stdlib.h>
9
10 #define N 1024
11 long int u[N], m, n, o;
12
13 __attribute__((noipa)) void
14 foo (void)
15 {
16 int i = -1;
17 #pragma omp master taskloop simd reduction (+:m) grainsize (64)
18 for (i = 0; i < N; ++i)
19 m += u[i];
20 if (i != (omp_get_thread_num () ? -1 : N))
21 abort ();
22 }
23
24 __attribute__((noipa)) void
25 bar (int x)
26 {
27 int i = -1;
28 #pragma omp master taskloop simd in_reduction (+:n) grainsize (64)
29 for (i = (x & 1) * (N / 2); i < (x & 1) * (N / 2) + (N / 2); i++)
30 n += 2 * u[i];
31 if (i != (omp_get_thread_num () ? -1 : (x & 1) * (N / 2) + (N / 2)))
32 abort ();
33 }
34
35 __attribute__((noipa)) void
36 baz (void)
37 {
38 int i;
39 #pragma omp parallel master taskloop simd reduction (+:o) grainsize (64)
40 for (i = 0; i < N; ++i)
41 o += u[i];
42 if (i != N)
43 abort ();
44 }
45
46 int
47 main ()
48 {
49 int i;
50 for (i = 0; i < N; ++i)
51 u[i] = i;
52 #pragma omp parallel
53 {
54 foo ();
55 #pragma omp taskgroup task_reduction (+:n)
56 {
57 bar (0);
58 bar (1);
59 }
60 }
61 baz ();
62 if (m != (long)(N - 1) * (N / 2) || n != (long)(N - 1) * N || o != m)
63 abort ();
64 return 0;
65 }