Fortran: OpenMP - fix simd with (last)private (PR97061) gcc/fortran/ChangeLog: PR fortran/97061 * trans-openmp.c (gfc_trans_omp_do): Handle simd with (last)private. gcc/testsuite/ChangeLog: PR fortran/97061 * gfortran.dg/gomp/openmp-simd-6.f90: New test. gcc/fortran/trans-openmp.c | 37 ++++++++------ gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 | 62 ++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 9ec0df204ac..378088a9d04 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -4401,20 +4401,29 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, if (clauses) { gfc_omp_namelist *n = NULL; - if (op != EXEC_OMP_DISTRIBUTE) - for (n = clauses->lists[(op == EXEC_OMP_SIMD && collapse == 1) - ? OMP_LIST_LINEAR : OMP_LIST_LASTPRIVATE]; + if (op == EXEC_OMP_SIMD && collapse == 1) + for (n = clauses->lists[OMP_LIST_LINEAR]; n != NULL; n = n->next) if (code->ext.iterator->var->symtree->n.sym == n->sym) - break; - if (n != NULL) - dovar_found = 1; - else if (n == NULL && op != EXEC_OMP_SIMD) + { + dovar_found = 3; + break; + } + if (n == NULL && op != EXEC_OMP_DISTRIBUTE) + for (n = clauses->lists[OMP_LIST_LASTPRIVATE]; + n != NULL; n = n->next) + if (code->ext.iterator->var->symtree->n.sym == n->sym) + { + dovar_found = 2; + break; + } + if (n == NULL) for (n = clauses->lists[OMP_LIST_PRIVATE]; n != NULL; n = n->next) if (code->ext.iterator->var->symtree->n.sym == n->sym) - break; - if (n != NULL) - dovar_found++; + { + dovar_found = 1; + break; + } } /* Evaluate all the expressions in the iterator. */ @@ -4512,7 +4521,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, if (orig_decls) TREE_VEC_ELT (orig_decls, i) = dovar_decl; - if (dovar_found == 2 + if (dovar_found == 3 && op == EXEC_OMP_SIMD && collapse == 1 && !simple) @@ -4536,7 +4545,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, omp_clauses = gfc_trans_add_clause (tmp, omp_clauses); } if (!simple) - dovar_found = 2; + dovar_found = 3; } else if (!dovar_found && !simple) { @@ -4544,7 +4553,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, OMP_CLAUSE_DECL (tmp) = dovar_decl; omp_clauses = gfc_trans_add_clause (tmp, omp_clauses); } - if (dovar_found == 2) + if (dovar_found > 1) { tree c = NULL; @@ -4612,7 +4621,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, } if (!simple) { - if (op != EXEC_OMP_SIMD) + if (op != EXEC_OMP_SIMD || dovar_found == 1) tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE); else if (collapse == 1) { diff --git a/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 new file mode 100644 index 00000000000..361e0dad343 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/openmp-simd-6.f90 @@ -0,0 +1,62 @@ +! { dg-additional-options "-fdump-tree-original" } +! +! PR fortran/97061 + +integer function f3 (a1, b1, u) + implicit none + integer :: a1, b1, d1 + integer u(0:1023) + !$omp teams distribute parallel do simd default(none) firstprivate (a1, b1) shared(u) lastprivate(d1) + do d1 = a1, b1-1 + u(d1) = 5 + end do +end + +subroutine foo(n, m, u) + implicit none + integer :: hh, ii, jj, n, m + integer u(0:1023) + !$omp simd private(ii) + do ii = n, m + u(ii) = 5 + end do + !$omp simd linear(jj:1) + do jj = 2, m+n + u(jj) = 6 + end do + !$omp simd + do hh = 2, m+n + u(hh) = 6 + end do +end + +subroutine bar(n, m, u) + implicit none + integer :: kkk, lll, ooo, ppp, n, m + integer u(:,:) + !$omp simd lastprivate(kkk) lastprivate(lll) collapse(2) + do kkk = n, m + do lll = n, m + u(kkk, lll) = 5 + end do + end do + !$omp simd private(kkk) private(lll) collapse(2) + do ooo = n, m + do ppp = n, m + u(ooo, ppp) = 5 + end do + end do +end + + +! { dg-final { scan-tree-dump-times "#pragma omp teams firstprivate\\(a1\\) firstprivate\\(b1\\) shared\\(u\\) default\\(none\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp distribute lastprivate\\(d1\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(a1\\) firstprivate\\(b1\\) lastprivate\\(d1\\) shared\\(u\\) default\\(none\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd lastprivate\\(d1\\)" 1 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp simd private\\(ii\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(jj:1\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(hh:1\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd lastprivate\\(kkk\\) lastprivate\\(lll\\) collapse\\(2\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd private\\(kkk\\) private\\(lll\\) collapse\\(2\\)" 1 "original" } }