From bc332ee63c582570dfd4754538d56e51c977a5b3 Mon Sep 17 00:00:00 2001 From: Kwok Cheung Yeung Date: Fri, 14 Aug 2020 05:14:32 -0700 Subject: [PATCH 1/2] [Fortran] OpenMP - permit lastprivate in distribute + SIMD fixes (PR94690) This is a backport from master of commit f884bef21cccc05d748fd7869cd641cbb4f6b6bb. gcc/fortran/ 2020-05-13 Tobias Burnus PR fortran/94690 * openmp.c (OMP_DISTRIBUTE_CLAUSES): Add OMP_CLAUSE_LASTPRIVATE. (gfc_resolve_do_iterator): Skip the private handling for SIMD as that is handled by ME code. * trans-openmp.c (gfc_trans_omp_do): Don't add private/lastprivate for dovar_found == 0, unless !simple. libgomp/ 2020-05-13 Tobias Burnus PR fortran/94690 * testsuite/libgomp.fortran/pr66199-3.f90: New. * testsuite/libgomp.fortran/pr66199-4.f90: New. * testsuite/libgomp.fortran/pr66199-5.f90: New. * testsuite/libgomp.fortran/pr66199-6.f90: New. * testsuite/libgomp.fortran/pr66199-7.f90: New. * testsuite/libgomp.fortran/pr66199-8.f90: New. * testsuite/libgomp.fortran/pr66199-9.f90: New. --- gcc/fortran/ChangeLog.omp | 12 ++++ gcc/fortran/openmp.c | 27 ++++++++- gcc/fortran/trans-openmp.c | 27 +++++---- libgomp/ChangeLog.omp | 14 +++++ libgomp/testsuite/libgomp.fortran/pr66199-3.f90 | 53 +++++++++++++++++ libgomp/testsuite/libgomp.fortran/pr66199-4.f90 | 60 +++++++++++++++++++ libgomp/testsuite/libgomp.fortran/pr66199-5.f90 | 71 +++++++++++++++++++++++ libgomp/testsuite/libgomp.fortran/pr66199-6.f90 | 42 ++++++++++++++ libgomp/testsuite/libgomp.fortran/pr66199-7.f90 | 72 +++++++++++++++++++++++ libgomp/testsuite/libgomp.fortran/pr66199-8.f90 | 76 +++++++++++++++++++++++++ libgomp/testsuite/libgomp.fortran/pr66199-9.f90 | 46 +++++++++++++++ 11 files changed, 485 insertions(+), 15 deletions(-) create mode 100644 libgomp/testsuite/libgomp.fortran/pr66199-3.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr66199-4.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr66199-5.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr66199-6.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr66199-7.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr66199-8.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/pr66199-9.f90 diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp index 99b939a..340a4dc 100644 --- a/gcc/fortran/ChangeLog.omp +++ b/gcc/fortran/ChangeLog.omp @@ -1,3 +1,15 @@ +2020-08-14 Kwok Cheung Yeung + + Backport from mainline + 2020-05-13 Tobias Burnus + + PR fortran/94690 + * openmp.c (OMP_DISTRIBUTE_CLAUSES): Add OMP_CLAUSE_LASTPRIVATE. + (gfc_resolve_do_iterator): Skip the private handling for SIMD as + that is handled by ME code. + * trans-openmp.c (gfc_trans_omp_do): Don't add private/lastprivate + for dovar_found == 0, unless !simple. + 2020-07-14 Tobias Burnus Backport from mainline diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 706933c..220b1a9 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -2615,7 +2615,7 @@ cleanup: | OMP_CLAUSE_SHARED | OMP_CLAUSE_REDUCTION) #define OMP_DISTRIBUTE_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ - | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE) + | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_DIST_SCHEDULE) #define OMP_SINGLE_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE) #define OMP_ORDERED_CLAUSES \ @@ -5703,6 +5703,31 @@ gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym, bool add_clause) if (omp_current_ctx->sharing_clauses->contains (sym)) return; + if (omp_current_ctx->is_openmp && omp_current_ctx->code->block) + { + /* SIMD is handled differently and, hence, ignored here. */ + gfc_code *omp_code = omp_current_ctx->code->block; + for ( ; omp_code->next; omp_code = omp_code->next) + switch (omp_code->op) + { + case EXEC_OMP_SIMD: + case EXEC_OMP_DO_SIMD: + case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_DISTRIBUTE_SIMD: + case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: + case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD: + case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: + case EXEC_OMP_TARGET_SIMD: + case EXEC_OMP_TASKLOOP_SIMD: + return; + default: + break; + } + } + if (! omp_current_ctx->private_iterators->add (sym) && add_clause) { gfc_omp_clauses *omp_clauses = omp_current_ctx->code->ext.omp_clauses; diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 1cc542f..9a0f363 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -4450,23 +4450,22 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, break; } } - if (!dovar_found) + if (!dovar_found && op == EXEC_OMP_SIMD) { - if (op == EXEC_OMP_SIMD) + if (collapse == 1) { - if (collapse == 1) - { - tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); - OMP_CLAUSE_LINEAR_STEP (tmp) = step; - OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1; - } - else - tmp = build_omp_clause (input_location, OMP_CLAUSE_LASTPRIVATE); - if (!simple) - dovar_found = 2; + tmp = build_omp_clause (input_location, OMP_CLAUSE_LINEAR); + OMP_CLAUSE_LINEAR_STEP (tmp) = step; + OMP_CLAUSE_LINEAR_NO_COPYIN (tmp) = 1; + OMP_CLAUSE_DECL (tmp) = dovar_decl; + omp_clauses = gfc_trans_add_clause (tmp, omp_clauses); } - else - tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); + if (!simple) + dovar_found = 2; + } + else if (!dovar_found && !simple) + { + tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); OMP_CLAUSE_DECL (tmp) = dovar_decl; omp_clauses = gfc_trans_add_clause (tmp, omp_clauses); } diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp index 383c1f7..ce7d7f5 100644 --- a/libgomp/ChangeLog.omp +++ b/libgomp/ChangeLog.omp @@ -1,3 +1,17 @@ +2020-08-14 Kwok Cheung Yeung + + Backport from mainline + 2020-05-13 Tobias Burnus + + PR fortran/94690 + * testsuite/libgomp.fortran/pr66199-3.f90: New. + * testsuite/libgomp.fortran/pr66199-4.f90: New. + * testsuite/libgomp.fortran/pr66199-5.f90: New. + * testsuite/libgomp.fortran/pr66199-6.f90: New. + * testsuite/libgomp.fortran/pr66199-7.f90: New. + * testsuite/libgomp.fortran/pr66199-8.f90: New. + * testsuite/libgomp.fortran/pr66199-9.f90: New. + 2020-08-12 Kwok Cheung Yeung * testsuite/libgomp.c-c++-common/reduction-16.c: New. diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-3.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-3.f90 new file mode 100644 index 0000000..7c596dc --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/pr66199-3.f90 @@ -0,0 +1,53 @@ +! { dg-do run } +! +! PR fortran/94690 +! PR middle-end/66199 + +module m + integer u(0:1024-1), v(0:1024-1), w(0:1024-1) +contains + +integer(8) function f1 (a, b) + implicit none + integer, value :: a, b + integer(8) :: d + !$omp parallel do lastprivate (d) default(none) firstprivate (a, b) shared(u, v, w) + do d = a, b-1 + u(d) = v(d) + w(d) + end do + f1 = d +end + +integer(8) function f2 (a, b, c) + implicit none + integer, value :: a, b, c + integer(8) :: d, e + !$omp parallel do lastprivate (d) default(none) firstprivate (a, b) shared(u, v, w) linear(c:5) lastprivate(e) + do d = a, b-1 + u(d) = v(d) + w(d) + c = c + 5 + e = c + end do + f2 = d + c + e +end + +integer(8) function f3 (a1, b1, a2, b2) + implicit none + integer, value :: a1, b1, a2, b2 + integer(8) d1, d2 + !$omp parallel do default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) lastprivate(d1, d2) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + f3 = d1 + d2 +end +end module m + +program main + use m + if (f1 (0, 1024) /= 1024) stop 1 + if (f2 (0, 1024, 17) /= 1024 + 2 * (17 + 5 * 1024)) stop 2 + if (f3 (0, 32, 0, 32) /= 64) stop 3 +end program main diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-4.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-4.f90 new file mode 100644 index 0000000..17b62a6 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/pr66199-4.f90 @@ -0,0 +1,60 @@ +! { dg-do run } +! +! PR fortran/94690 +! PR middle-end/66199 + +module m + implicit none + integer u(0:1023), v(0:1023), w(0:1023) + !$omp declare target (u, v, w) + +contains + +subroutine f1 (a, b) + integer a, b, d + !$omp target teams distribute parallel do default(none) firstprivate (a, b) shared(u, v, w) + do d = a, b-1 + u(d) = v(d) + w(d) + end do +end + +subroutine f2 (a, b, c) + integer a, b, c, d, e + !$omp target teams distribute parallel do default(none) firstprivate (a, b, c) shared(u, v, w) lastprivate(d, e) + do d = a, b-1 + u(d) = v(d) + w(d) + e = c + d * 5 + end do +end + +subroutine f3 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target teams distribute parallel do default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) & + !$omp& lastprivate(d1, d2) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do +end + +subroutine f4 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target teams distribute parallel do default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) & + !$omp& collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do +end +end module m + +program main + use m + implicit none + call f1 (0, 1024) + call f2 (0, 1024, 17) + call f3 (0, 32, 0, 32) + call f4 (0, 32, 0, 32) +end diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-5.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-5.f90 new file mode 100644 index 0000000..9482f08 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/pr66199-5.f90 @@ -0,0 +1,71 @@ +! { dg-do run } +! +! PR fortran/94690 +! PR middle-end/66199 + +module m + implicit none + integer u(0:1023), v(0:1023), w(0:1023) + !$omp declare target (u, v, w) + +contains + +integer function f1 (a, b) + integer :: a, b, d + !$omp target map(from: d) + !$omp teams distribute parallel do simd default(none) firstprivate (a, b) shared(u, v, w) + do d = a, b-1 + u(d) = v(d) + w(d) + end do + !$omp end target + f1 = d +end + +integer function f2 (a, b, c) + integer :: a, b, c, d, e + !$omp target map(from: d, e) + !$omp teams distribute parallel do simd default(none) firstprivate (a, b, c) shared(u, v, w) linear(d) lastprivate(e) + do d = a, b-1 + u(d) = v(d) + w(d) + e = c + d * 5 + end do + !$omp end target + f2 = d + e +end + +integer function f3 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams distribute parallel do simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) lastprivate(d1, d2) & + !$omp& collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end target + f3 = d1 + d2 +end + +integer function f4 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams distribute parallel do simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end target + f4 = d1 + d2 +end +end module + +program main + use m + implicit none + if (f1 (0, 1024) /= 1024) stop 1 + if (f2 (0, 1024, 17) /= 1024 + (17 + 5 * 1023)) stop 2 + if (f3 (0, 32, 0, 32) /= 64) stop 3 + if (f4 (0, 32, 0, 32) /= 64) stop 3 +end diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-6.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-6.f90 new file mode 100644 index 0000000..f73f683 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/pr66199-6.f90 @@ -0,0 +1,42 @@ +! { dg-do run } +! +! PR fortran/94690 +! PR middle-end/66199 + +module m + implicit none + integer :: u(0:1023), v(0:1023), w(0:1023) + !$omp declare target (u, v, w) + +contains + +integer function f2 (a, b, c) + integer :: a, b, c, d, e + !$omp target map(from: d, e) + !$omp teams distribute parallel do default(none) firstprivate (a, b, c) shared(u, v, w) lastprivate(d, e) + do d = a, b-1 + u(d) = v(d) + w(d) + e = c + d * 5 + end do + !$omp end target + f2 = d + e +end + +integer function f3 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams distribute parallel do default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) lastprivate(d1, d2) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end target + f3 = d1 + d2 +end +end module m + +use m + if (f2 (0, 1024, 17) /= 1024 + (17 + 5 * 1023)) stop 1 + if (f3 (0, 32, 0, 32) /= 64) stop 2 +end diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-7.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-7.f90 new file mode 100644 index 0000000..2bd9468 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/pr66199-7.f90 @@ -0,0 +1,72 @@ +! { dg-do run } +! +! PR fortran/94690 +! PR middle-end/66199 + +module m + implicit none + integer u(1024), v(1024), w(1024) + !$omp declare target (v, u, w) + +contains + +integer function f1 (a, b) + integer :: a, b, d + !$omp target map(from: d) + !$omp teams distribute simd default(none) firstprivate (a, b) shared(u, v, w) + do d = a, b-1 + u(d) = v(d) + w(d) + end do + !$omp end teams distribute simd + !$omp end target + f1 = d +end + +integer function f2 (a, b, c) + integer a, b, c, d, e + !$omp target map(from: d, e) + !$omp teams distribute simd default(none) firstprivate (a, b, c) shared(u, v, w) linear(d) lastprivate(e) + do d = a, b-1 + u(d) = v(d) + w(d) + e = c + d * 5 + end do + !$omp end teams distribute simd + !$omp end target + f2 = d + e +end + +integer function f3 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams distribute simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) lastprivate(d1, d2) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end teams distribute simd + !$omp end target + f3 = d1 + d2 +end + +integer function f4 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams distribute simd default(none) firstprivate (a1, b1, a2, b2) shared(u, v, w) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end teams distribute simd + !$omp end target + f4 = d1 + d2 +end +end module + +use m + if (f1 (0, 1024) /= 1024) stop 1 + if (f2 (0, 1024, 17) /= 1024 + (17 + 5 * 1023)) stop 2 + if (f3 (0, 32, 0, 32) /= 64) stop 3 + if (f4 (0, 32, 0, 32) /= 64) stop 4 +end diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-8.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-8.f90 new file mode 100644 index 0000000..8a21c6f --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/pr66199-8.f90 @@ -0,0 +1,76 @@ +! { dg-do run } +! +! PR fortran/94690 +! PR middle-end/66199 + +module m + implicit none + integer u(0:1023), v(0:1023), w(0:1023) + !$omp declare target (u, v, w) + +contains + +integer function f1 (a, b) + integer :: a, b, d + !$omp target map(from: d) + !$omp teams default(none) shared(a, b, d, u, v, w) + !$omp distribute simd firstprivate (a, b) + do d = a, b-1 + u(d) = v(d) + w(d) + end do + !$omp end teams + !$omp end target + f1 = d +end + +integer function f2 (a, b, c) + integer a, b, c, d, e + !$omp target map(from: d, e) + !$omp teams default(none) firstprivate (a, b, c) shared(d, e, u, v, w) + !$omp distribute simd linear(d) lastprivate(e) + do d = a, b-1 + u(d) = v(d) + w(d) + e = c + d * 5 + end do + !$omp end teams + !$omp end target + f2 = d + e +end + +integer function f3 (a1, b1, a2, b2) + integer a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams default(none) shared(a1, b1, a2, b2, d1, d2, u, v, w) + !$omp distribute simd firstprivate (a1, b1, a2, b2) lastprivate(d1, d2) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end teams + !$omp end target + f3 = d1 + d2 +end + +integer function f4 (a1, b1, a2, b2) + integer a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams default(none) firstprivate (a1, b1, a2, b2) shared(d1, d2, u, v, w) + !$omp distribute simd collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end teams + !$omp end target + f4 = d1 + d2 +end +end module m + +use m + if (f1 (0, 1024) /= 1024) stop 1 + if (f2 (0, 1024, 17) /= 1024 + (17 + 5 * 1023)) stop 2 + if (f3 (0, 32, 0, 32) /= 64) stop 3 + if (f4 (0, 32, 0, 32) /= 64) stop 4 +end diff --git a/libgomp/testsuite/libgomp.fortran/pr66199-9.f90 b/libgomp/testsuite/libgomp.fortran/pr66199-9.f90 new file mode 100644 index 0000000..5dde7f8 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/pr66199-9.f90 @@ -0,0 +1,46 @@ +! { dg-do run } +! +! PR fortran/94690 +! PR middle-end/66199 + +module m + implicit none + integer u(1024), v(1024), w(1024) + !$omp declare target (u, v, w) + +contains + +integer function f2 (a, b, c) + integer :: a, b, c, d, e + !$omp target map(from: d, e) + !$omp teams default(none) firstprivate (a, b, c) shared(d, e, u, v, w) + !$omp distribute lastprivate(d, e) + do d = a, b-1 + u(d) = v(d) + w(d) + e = c + d * 5 + end do + !$omp end teams + !$omp end target + f2 = d + e +end + +integer function f3 (a1, b1, a2, b2) + integer :: a1, b1, a2, b2, d1, d2 + !$omp target map(from: d1, d2) + !$omp teams default(none) shared(a1, b1, a2, b2, d1, d2, u, v, w) + !$omp distribute firstprivate (a1, b1, a2, b2) lastprivate(d1, d2) collapse(2) + do d1 = a1, b1-1 + do d2 = a2, b2-1 + u(d1 * 32 + d2) = v(d1 * 32 + d2) + w(d1 * 32 + d2) + end do + end do + !$omp end teams + !$omp end target + f3 = d1 + d2 +end +end module + +use m + if (f2 (0, 1024, 17) /= 1024 + (17 + 5 * 1023)) stop 1 + if (f3 (0, 32, 0, 32) /= 64) stop 2 +end -- 2.8.1