diff --git a/libgomp/target.c b/libgomp/target.c index 57634839c8f..73c99c7c2e7 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -2813,6 +2813,7 @@ GOMP_target_ext (int device, void (*fn) (void *), size_t mapnum, { struct gomp_team *team = gomp_new_team (1); struct gomp_task *task = thr->task; + struct gomp_task **implicit_task = &task; struct gomp_task_icv *icv = task ? &task->icv : &gomp_global_icv; team->prev_ts = thr->ts; thr->ts.team = team; @@ -2825,15 +2826,23 @@ GOMP_target_ext (int device, void (*fn) (void *), size_t mapnum, thr->ts.static_trip = 0; thr->task = &team->implicit_task[0]; gomp_init_task (thr->task, NULL, icv); - if (task) + while (*implicit_task + && (*implicit_task)->kind != GOMP_TASK_IMPLICIT) + implicit_task = &(*implicit_task)->parent; + if (*implicit_task) { - thr->task = task; + thr->task = *implicit_task; gomp_end_task (); - free (task); + free (*implicit_task); thr->task = &team->implicit_task[0]; } else pthread_setspecific (gomp_thread_destructor, thr); + if (implicit_task != &task) + { + *implicit_task = thr->task; + thr->task = task; + } } if (thr->ts.team && !thr->task->final_task) diff --git a/libgomp/task.c b/libgomp/task.c index 30cd046df2a..7766535d1aa 100644 --- a/libgomp/task.c +++ b/libgomp/task.c @@ -2465,6 +2465,7 @@ gomp_create_artificial_team (void) struct gomp_task_icv *icv; struct gomp_team *team = gomp_new_team (1); struct gomp_task *task = thr->task; + struct gomp_task **implicit_task = &task; icv = task ? &task->icv : &gomp_global_icv; team->prev_ts = thr->ts; thr->ts.team = team; @@ -2477,17 +2478,25 @@ gomp_create_artificial_team (void) thr->ts.static_trip = 0; thr->task = &team->implicit_task[0]; gomp_init_task (thr->task, NULL, icv); - if (task) + while (*implicit_task + && (*implicit_task)->kind != GOMP_TASK_IMPLICIT) + implicit_task = &(*implicit_task)->parent; + if (*implicit_task) { - thr->task = task; + thr->task = *implicit_task; gomp_end_task (); - free (task); + free (*implicit_task); thr->task = &team->implicit_task[0]; } #ifdef LIBGOMP_USE_PTHREADS else pthread_setspecific (gomp_thread_destructor, thr); #endif + if (implicit_task != &task) + { + *implicit_task = thr->task; + thr->task = task; + } } /* The format of data is: diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-17.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-17.c new file mode 100644 index 00000000000..4a8d1e8bb73 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-17.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ + +#include +#include + +int a; + +int +main () +{ + #pragma omp task final (1) + { + if (!omp_in_final ()) + abort (); + #pragma omp task + { + if (!omp_in_final ()) + abort (); + #pragma omp taskgroup task_reduction (+: a) + { + if (!omp_in_final ()) + abort (); + #pragma omp task in_reduction (+: a) + { + ++a; + if (!omp_in_final ()) + abort (); + } + } + if (!omp_in_final ()) + abort (); + #pragma omp taskwait + } + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-reduction-18.c b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-18.c new file mode 100644 index 00000000000..483f4406f6f --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/task-reduction-18.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ + +int a; + +int +main () +{ + #pragma omp task + { + #pragma omp taskgroup task_reduction (+: a) + { + #pragma omp task in_reduction (+: a) + ++a; + } + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/task-7.c b/libgomp/testsuite/libgomp.c/task-7.c new file mode 100644 index 00000000000..0307575f978 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/task-7.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ + +#include +#include + +int +main () +{ + #pragma omp task final (1) + { + if (!omp_in_final ()) + abort (); + #pragma omp task + { + if (!omp_in_final ()) + abort (); + #pragma omp target nowait + if (omp_in_final ()) + abort (); + if (!omp_in_final ()) + abort (); + #pragma omp taskwait + } + } + return 0; +} diff --git a/libgomp/testsuite/libgomp.c/task-8.c b/libgomp/testsuite/libgomp.c/task-8.c new file mode 100644 index 00000000000..f03aef6a030 --- /dev/null +++ b/libgomp/testsuite/libgomp.c/task-8.c @@ -0,0 +1,14 @@ +/* { dg-do run } */ + +int +main () +{ + int i = 0; + #pragma omp task + { + #pragma omp target nowait private (i) + i = 1; + #pragma omp taskwait + } + return 0; +}