1 // RUN: %libomp-compile-and-run
2 
3 // Parsing error until gcc8:
4 // UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7, gcc-8
5 
6 // Missing GOMP_taskgroup_reduction_(un)register in LLVM/OpenMP
7 // Should be removed once the functions are implemented
8 // XFAIL: gcc-9, gcc-10
9 
10 #include <stdio.h>
11 #include <omp.h>
12 
13 int r;
14 
15 int work(int k, int l)
16 {
17   return k + l + 1;
18 }
19 void bar(int i) {
20   #pragma omp taskgroup task_reduction(+:r)
21  { int th_gen = omp_get_thread_num();
22   #pragma omp task in_reduction(+:r) firstprivate(i, th_gen)
23   {
24     r += work(i, 0);
25 printf("executing task (%d, 0), th %d (gen by th %d)\n", i, omp_get_thread_num(), th_gen);
26   }
27   #pragma omp task in_reduction(+:r) firstprivate(i, th_gen)
28   {
29     r += work(i, 1);
30 printf("executing task (%d, 1), th %d (gen by th %d)\n", i, omp_get_thread_num(), th_gen);
31   }
32  }
33 }
34 int foo() {
35   int i;
36   int th_gen = omp_get_thread_num();
37   #pragma omp taskgroup task_reduction(+:r)
38   {
39     bar(0);
40   }
41 printf("th %d passed bar0\n", th_gen);
42   #pragma omp taskloop reduction(+:r) firstprivate(th_gen)
43   for (i = 1; i < 4; ++i) {
44     bar(i);
45 printf("th %d (gen by th %d) passed bar%d in taskloop\n", omp_get_thread_num(), th_gen, i);
46   #pragma omp task in_reduction(+:r)
47     r += i;
48   }
49   return 0;
50 }
51 // res = 2*((1+2)+(2+3)+(3+4)+(4+5)+1+2+3) = 60
52 #define res 60
53 int main()
54 {
55   r = 0;
56   #pragma omp parallel num_threads(2)
57     foo();
58   if (r == res) {
59     return 0;
60   } else {
61     printf("error r = %d (!= %d)\n", r, res);
62     return 1;
63   }
64 }
65