1 // RUN: %libomptarget-compilexx-run-and-check-aarch64-unknown-linux-gnu
2 // RUN: %libomptarget-compilexx-run-and-check-powerpc64-ibm-linux-gnu
3 // RUN: %libomptarget-compilexx-run-and-check-powerpc64le-ibm-linux-gnu
4 // RUN: %libomptarget-compilexx-run-and-check-x86_64-pc-linux-gnu
5 
6 #include <omp.h>
7 #include <stdio.h>
8 
9 #define N 1024
10 
11 int A[N];
12 int B[N];
13 int C[N];
14 int main() {
15   for (int i = 0; i < N; i++)
16     A[i] = B[i] = i;
17 
18 #pragma omp parallel num_threads(2)
19   {
20     if (omp_get_thread_num() == 1) {
21 // map data A & B and move to
22 #pragma omp target enter data map(to : A, B) depend(out : A[0]) nowait
23 
24 // no data move since already mapped
25 #pragma omp target map(A, B) depend(out : A[0]) nowait
26       {
27         for (int i = 0; i < N; i++)
28           ++A[i];
29         for (int i = 0; i < N; i++)
30           ++B[i];
31       }
32 
33 // no data move since already mapped
34 #pragma omp target teams num_teams(1) map(A, B) depend(out : A[0]) nowait
35       {
36         for (int i = 0; i < N; i++)
37           ++A[i];
38         for (int i = 0; i < N; i++)
39           ++B[i];
40       }
41 
42 // A updated via update
43 #pragma omp target update from(A) depend(out : A[0]) nowait
44 
45 // B updated via exit, A just released
46 #pragma omp target exit data map(release                                       \
47                                  : A) map(from                                 \
48                                           : B) depend(out                      \
49                                                       : A[0]) nowait
50     } // if
51   }   // parallel
52 
53   int Sum = 0;
54   for (int i = 0; i < N; i++)
55     Sum += A[i] + B[i];
56   // Sum is 2 * N * (2 + N - 1 + 2) / 2
57   // CHECK: Sum = 1051648.
58   printf("Sum = %d.\n", Sum);
59 
60   return Sum != 2 * N * (2 + N - 1 + 2) / 2;
61 }
62 
63