OpenMP/Fortran: Permit end-clause on directive gcc/fortran/ChangeLog: * openmp.cc (OMP_DO_CLAUSES, OMP_SCOPE_CLAUSES, OMP_SECTIONS_CLAUSES, OMP_SINGLE_CLAUSES): Add 'nowait'. (gfc_match_omp_distribute_parallel_do, gfc_match_omp_distribute_parallel_do_simd, gfc_match_omp_parallel_do, gfc_match_omp_parallel_do_simd, gfc_match_omp_parallel_sections, gfc_match_omp_teams_distribute_parallel_do, gfc_match_omp_teams_distribute_parallel_do_simd): Disallow 'nowait'. gfc_match_omp_workshare): Match 'nowait' clause. (gfc_match_omp_end_single): Use clause matcher for 'nowait'. (resolve_omp_clauses): Reject 'nowait' + 'copyprivate'. * parse.cc (decode_omp_directive): Break too long line. (parse_omp_do, parse_omp_structured_block): Diagnose duplicated 'nowait' clause. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2): Mark end-directive as Y. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/copyprivate-1.f90: New test. * gfortran.dg/gomp/copyprivate-2.f90: New test. * gfortran.dg/gomp/nowait-4.f90: New test. * gfortran.dg/gomp/nowait-5.f90: New test. * gfortran.dg/gomp/nowait-6.f90: New test. gcc/fortran/openmp.cc | 55 ++-- gcc/fortran/parse.cc | 33 ++- gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90 | 21 ++ gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90 | 69 +++++ gcc/testsuite/gfortran.dg/gomp/nowait-4.f90 | 315 +++++++++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/nowait-5.f90 | 118 +++++++++ gcc/testsuite/gfortran.dg/gomp/nowait-6.f90 | 92 +++++++ libgomp/libgomp.texi | 2 +- 8 files changed, 673 insertions(+), 32 deletions(-) diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 594907714ff..b3b6fc17828 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -3795,17 +3795,19 @@ cleanup: (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \ | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \ - | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE \ + | OMP_CLAUSE_NOWAIT) #define OMP_LOOP_CLAUSES \ (omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER \ | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION) #define OMP_SCOPE_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) |OMP_CLAUSE_FIRSTPRIVATE \ - | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT) #define OMP_SECTIONS_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ - | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \ + | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT) #define OMP_SIMD_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \ | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \ @@ -3855,7 +3857,7 @@ cleanup: | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE) #define OMP_SINGLE_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ - | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_COPYPRIVATE) #define OMP_ORDERED_CLAUSES \ (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD) #define OMP_DECLARE_TARGET_CLAUSES \ @@ -4020,8 +4022,8 @@ gfc_match_omp_distribute_parallel_do (void) return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO, (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES) - & ~(omp_mask (OMP_CLAUSE_ORDERED)) - & ~(omp_mask (OMP_CLAUSE_LINEAR))); + & ~(omp_mask (OMP_CLAUSE_ORDERED) + | OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT)); } @@ -4031,7 +4033,7 @@ gfc_match_omp_distribute_parallel_do_simd (void) return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD, (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES) - & ~(omp_mask (OMP_CLAUSE_ORDERED))); + & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT)); } @@ -5332,7 +5334,8 @@ match gfc_match_omp_parallel_do (void) { return match_omp (EXEC_OMP_PARALLEL_DO, - OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES); + (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_NOWAIT))); } @@ -5340,7 +5343,8 @@ match gfc_match_omp_parallel_do_simd (void) { return match_omp (EXEC_OMP_PARALLEL_DO_SIMD, - OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES); + (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_NOWAIT))); } @@ -5396,7 +5400,8 @@ match gfc_match_omp_parallel_sections (void) { return match_omp (EXEC_OMP_PARALLEL_SECTIONS, - OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES); + (OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_NOWAIT))); } @@ -5882,8 +5887,8 @@ gfc_match_omp_teams_distribute_parallel_do (void) return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO, (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES) - & ~(omp_mask (OMP_CLAUSE_ORDERED)) - & ~(omp_mask (OMP_CLAUSE_LINEAR))); + & ~(omp_mask (OMP_CLAUSE_ORDERED) + | OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT)); } @@ -5893,7 +5898,8 @@ gfc_match_omp_teams_distribute_parallel_do_simd (void) return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD, (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES - | OMP_SIMD_CLAUSES) & ~(omp_mask (OMP_CLAUSE_ORDERED))); + | OMP_SIMD_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT)); } @@ -5909,13 +5915,11 @@ gfc_match_omp_teams_distribute_simd (void) match gfc_match_omp_workshare (void) { - if (gfc_match_omp_eos () != MATCH_YES) - { - gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C"); - return MATCH_ERROR; - } + gfc_omp_clauses *c; + if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_NOWAIT)) != MATCH_YES) + return MATCH_ERROR; new_st.op = EXEC_OMP_WORKSHARE; - new_st.ext.omp_clauses = gfc_get_omp_clauses (); + new_st.ext.omp_clauses = c; return MATCH_YES; } @@ -6220,14 +6224,8 @@ match gfc_match_omp_end_single (void) { gfc_omp_clauses *c; - if (gfc_match ("% nowait") == MATCH_YES) - { - new_st.op = EXEC_OMP_END_NOWAIT; - new_st.ext.omp_bool = true; - return MATCH_YES; - } - if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE)) - != MATCH_YES) + if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE) + | OMP_CLAUSE_NOWAIT) != MATCH_YES) return MATCH_ERROR; new_st.op = EXEC_OMP_END_SINGLE; new_st.ext.omp_clauses = c; @@ -6954,6 +6952,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, } break; case OMP_LIST_COPYPRIVATE: + if (omp_clauses->nowait) + gfc_error ("NOWAIT clause must not be be used with COPYPRIVATE " + "clause at %L", &n->where); for (; n != NULL; n = n->next) { if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE) diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index 80492c952aa..8a1bfda64d6 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -939,7 +939,8 @@ decode_omp_directive (void) matchs ("end ordered", gfc_match_omp_eos_error, ST_OMP_END_ORDERED); matchs ("end parallel do simd", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO_SIMD); - matcho ("end parallel do", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO); + matcho ("end parallel do", gfc_match_omp_eos_error, + ST_OMP_END_PARALLEL_DO); matcho ("end parallel loop", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_LOOP); matcho ("end parallel masked taskloop simd", gfc_match_omp_eos_error, @@ -5284,7 +5285,13 @@ parse_omp_do (gfc_statement omp_st) if (st == omp_end_st) { if (new_st.op == EXEC_OMP_END_NOWAIT) - cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool; + { + if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool) + gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C", + gfc_ascii_statement (omp_st), + gfc_ascii_statement (omp_end_st)); + cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool; + } else gcc_assert (new_st.op == EXEC_NOP); gfc_clear_new_st (); @@ -5720,6 +5727,10 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) switch (new_st.op) { case EXEC_OMP_END_NOWAIT: + if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool) + gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C", + gfc_ascii_statement (omp_st), + gfc_ascii_statement (omp_end_st)); cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool; break; case EXEC_OMP_END_CRITICAL: @@ -5734,8 +5745,22 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) new_st.ext.omp_name = NULL; break; case EXEC_OMP_END_SINGLE: - cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] - = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; + if (cp->ext.omp_clauses->nowait && new_st.ext.omp_clauses->nowait) + gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C", + gfc_ascii_statement (omp_st), + gfc_ascii_statement (omp_end_st)); + cp->ext.omp_clauses->nowait |= new_st.ext.omp_clauses->nowait; + if (cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]) + { + gfc_omp_namelist *nl; + for (nl = cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; + nl->next; nl = nl->next); + ; + nl->next = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; + } + else + cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] + = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] = NULL; gfc_free_omp_clauses (new_st.ext.omp_clauses); break; diff --git a/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90 b/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90 new file mode 100644 index 00000000000..eb2c865818e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/copyprivate-1.f90 @@ -0,0 +1,21 @@ +! based on pr59467.f90 but COPYPRIVATE on the directive +! { dg-additional-options "-fdump-tree-original" } + + FUNCTION t() + INTEGER :: a, b, t + a = 0 + b = 0 + t = b + b = 0 + !$OMP PARALLEL REDUCTION(+:b) + !$OMP SINGLE COPYPRIVATE (b) + !$OMP ATOMIC WRITE + b = 6 + !$OMP END SINGLE + !$OMP END PARALLEL + t = t + b + END FUNCTION + +! { dg-final { scan-tree-dump-times "#pragma omp parallel reduction\\(\\+:b\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp single copyprivate\\(b\\)" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp atomic relaxed" 1 "original" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90 b/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90 new file mode 100644 index 00000000000..6615ed8688a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/copyprivate-2.f90 @@ -0,0 +1,69 @@ + FUNCTION t() + INTEGER :: a, b, t + a = 0 + t = b + b = 0 + !$OMP PARALLEL REDUCTION(+:b) + !$OMP SINGLE COPYPRIVATE (b) NOWAIT ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" } + !$OMP ATOMIC WRITE + b = 6 + !$OMP END SINGLE + !$OMP END PARALLEL + t = t + b + END FUNCTION + + FUNCTION t2() + INTEGER :: a, b, t2 + a = 0 + t2 = b + b = 0 + !$OMP PARALLEL REDUCTION(+:b) + !$OMP SINGLE NOWAIT COPYPRIVATE (b) ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" } + !$OMP ATOMIC WRITE + b = 6 + !$OMP END SINGLE + !$OMP END PARALLEL + t2 = t2 + b + END FUNCTION + + FUNCTION t3() + INTEGER :: a, b, t3 + a = 0 + t3 = b + b = 0 + !$OMP PARALLEL REDUCTION(+:b) + !$OMP SINGLE COPYPRIVATE (b) ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" } + !$OMP ATOMIC WRITE + b = 6 + !$OMP END SINGLE NOWAIT + !$OMP END PARALLEL + t3 = t3 + b + END FUNCTION + + FUNCTION t4() + INTEGER :: a, b, t4 + a = 0 + t4 = b + b = 0 + !$OMP PARALLEL REDUCTION(+:b) + !$OMP SINGLE + !$OMP ATOMIC WRITE + b = 6 + !$OMP END SINGLE NOWAIT COPYPRIVATE (b) ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" } + !$OMP END PARALLEL + t4 = t4 + b + END FUNCTION + + FUNCTION t5() + INTEGER :: a, b, t5 + a = 0 + t5 = b + b = 0 + !$OMP PARALLEL REDUCTION(+:b) + !$OMP SINGLE + !$OMP ATOMIC WRITE + b = 6 + !$OMP END SINGLE COPYPRIVATE (b) NOWAIT ! { dg-error "NOWAIT clause must not be be used with COPYPRIVATE clause" } + !$OMP END PARALLEL + t5 = t5 + b + END FUNCTION diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90 new file mode 100644 index 00000000000..8472df95f83 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/nowait-4.f90 @@ -0,0 +1,315 @@ +! Cross check that it is accepted without nowait +subroutine bar() +implicit none +integer :: i, a(5) +!$omp atomic write +i = 5 +!$omp end atomic + +!$omp critical +!$omp end critical + +!$omp distribute +do i = 1, 5 +end do +!$omp end distribute + +!$omp distribute parallel do +do i = 1, 5 +end do +!$omp end distribute parallel do + +!$omp distribute parallel do simd +do i = 1, 5 +end do +!$omp end distribute parallel do simd + +!$omp distribute simd +do i = 1, 5 +end do +!$omp end distribute simd + +!$omp masked +!$omp end masked + +!$omp masked taskloop +do i = 1, 5 +end do +!$omp end masked taskloop + +!$omp masked taskloop simd +do i = 1, 5 +end do +!$omp end masked taskloop simd + +!$omp master +!$omp end master + +!$omp master taskloop +do i = 1, 5 +end do +!$omp end master taskloop + +!$omp master taskloop simd +do i = 1, 5 +end do +!$omp end master taskloop simd + +!$omp ordered +!$omp end ordered + +!$omp parallel +!$omp end parallel + +!$omp parallel workshare +a(:) = 5 +!$omp end parallel workshare + +!$omp parallel do +do i = 1, 5 +end do +!$omp end parallel do + +!$omp parallel do simd +do i = 1, 5 +end do +!$omp end parallel do simd + +!$omp parallel sections + !$omp section + block; end block +!$omp end parallel sections + +!$omp parallel masked +!$omp end parallel masked + +!$omp parallel masked taskloop +do i = 1, 5 +end do +!$omp end parallel masked taskloop + +!$omp parallel masked taskloop simd +do i = 1, 5 +end do +!$omp end parallel masked taskloop simd + +!$omp parallel master +!$omp end parallel master + +!$omp parallel master taskloop +do i = 1, 5 +end do +!$omp end parallel master taskloop + +!$omp parallel master taskloop simd +do i = 1, 5 +end do +!$omp end parallel master taskloop simd + +!$omp simd +do i = 1, 5 +end do +!$omp end simd + +!$omp task +!$omp end task + +!$omp taskgroup +!$omp end taskgroup + +!$omp taskloop +do i = 1, 5 +end do +!$omp end taskloop + +!$omp taskloop simd +do i = 1, 5 +end do +!$omp end taskloop simd + +!$omp teams +!$omp end teams + +!$omp teams distribute +do i = 1, 5 +end do +!$omp end teams distribute + +!$omp teams distribute parallel do +do i = 1, 5 +end do +!$omp end teams distribute parallel do + +!$omp teams distribute parallel do simd +do i = 1, 5 +end do +!$omp end teams distribute parallel do simd + +!$omp teams distribute simd +do i = 1, 5 +end do +!$omp end teams distribute simd + +!$omp target data map(tofrom:i) +!$omp end target data + +end + +! invalid nowait + +subroutine foo +implicit none +integer :: i, a(5) +!$omp atomic write nowait ! { dg-error "Failed to match clause" } +i = 5 +!$omp end atomic ! { dg-error "Unexpected ..OMP END " } + +!$omp critical nowait ! { dg-error "Failed to match clause" } +!$omp end critical ! { dg-error "Unexpected ..OMP END " } + +!$omp distribute nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end distribute ! { dg-error "Unexpected ..OMP END " } + +!$omp distribute parallel do nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end distribute parallel do ! { dg-error "Unexpected ..OMP END " } + +!$omp distribute parallel do simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end distribute parallel do simd ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel sections nowait ! { dg-error "Failed to match clause" } + !$omp section ! { dg-error "Unexpected ..OMP SECTION statement" } + block; end block +!$omp end parallel sections ! { dg-error "Unexpected ..OMP END " } + +!$omp distribute simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end distribute simd ! { dg-error "Unexpected ..OMP END " } + +!$omp masked nowait ! { dg-error "Failed to match clause" } +!$omp end masked ! { dg-error "Unexpected ..OMP END " } + +!$omp masked taskloop nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end masked taskloop ! { dg-error "Unexpected ..OMP END " } + +!$omp masked taskloop simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end masked taskloop simd ! { dg-error "Unexpected ..OMP END " } + +!$omp master nowait ! { dg-error "Unexpected junk" } +!$omp end master ! { dg-error "Unexpected ..OMP END " } + +!$omp master taskloop nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end master taskloop ! { dg-error "Unexpected ..OMP END " } + +!$omp master taskloop simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end master taskloop simd ! { dg-error "Unexpected ..OMP END " } + +!$omp ordered nowait ! { dg-error "Failed to match clause" } +!$omp end ordered ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel nowait ! { dg-error "Failed to match clause" } +!$omp end parallel ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel workshare nowait ! { dg-error "Failed to match clause" } +a(:) = 5 +!$omp end parallel workshare ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel do nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end parallel do ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel do simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end parallel do simd ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel masked nowait ! { dg-error "Failed to match clause" } +!$omp end parallel masked ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel masked taskloop nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end parallel masked taskloop ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel masked taskloop simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end parallel masked taskloop simd ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel master nowait ! { dg-error "Failed to match clause" } +!$omp end parallel master ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel master taskloop nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end parallel master taskloop ! { dg-error "Unexpected ..OMP END " } + +!$omp parallel master taskloop simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end parallel master taskloop simd ! { dg-error "Unexpected ..OMP END " } + +!$omp simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end simd ! { dg-error "Unexpected ..OMP END " } + +!$omp task nowait ! { dg-error "Failed to match clause" } +!$omp end task ! { dg-error "Unexpected ..OMP END " } + +!$omp taskgroup nowait ! { dg-error "Failed to match clause" } +!$omp end taskgroup ! { dg-error "Unexpected ..OMP END " } + +!$omp taskloop nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end taskloop ! { dg-error "Unexpected ..OMP END " } + +!$omp taskloop simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end taskloop simd ! { dg-error "Unexpected ..OMP END " } + +!$omp teams nowait ! { dg-error "Failed to match clause" } +!$omp end teams ! { dg-error "Unexpected ..OMP END " } + +!$omp teams distribute nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end teams distribute ! { dg-error "Unexpected ..OMP END " } + +!$omp teams distribute parallel do nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end teams distribute parallel do ! { dg-error "Unexpected ..OMP END " } + +!$omp teams distribute parallel do simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end teams distribute parallel do simd ! { dg-error "Unexpected ..OMP END " } + +!$omp teams distribute simd nowait ! { dg-error "Failed to match clause" } +do i = 1, 5 +end do +!$omp end teams distribute simd ! { dg-error "Unexpected ..OMP END " } + +!$omp target data map(tofrom:i) nowait ! { dg-error "Failed to match clause" } +!$omp end target data ! { dg-error "Unexpected ..OMP END " } + +end +! { dg-prune-output "Unexpected end of file" } diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90 new file mode 100644 index 00000000000..41ead2f7eeb --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/nowait-5.f90 @@ -0,0 +1,118 @@ +! { dg-additional-options "-fdump-tree-original" } + +subroutine foo +implicit none +integer :: i, a(5) + +!$omp do nowait +do i = 1, 5 +end do +!$omp end do + +!$omp do simd nowait +do i = 1, 5 +end do +!$omp end do simd + +!$omp scope nowait +!$omp end scope + +!$omp sections nowait + !$omp section + block; end block +!$omp end sections + +!$omp single nowait +!$omp end single + +!$omp target nowait +!$omp end target + +!$omp target parallel nowait +!$omp end target parallel + +!$omp target parallel do nowait +do i = 1, 5 +end do +!$omp end target parallel do + +!$omp target parallel do simd nowait +do i = 1, 5 +end do +!$omp end target parallel do simd + +!$omp target parallel loop nowait +do i = 1, 5 +end do +!$omp end target parallel loop + +!$omp target teams distribute parallel do nowait +do i = 1, 5 +end do +!$omp end target teams distribute parallel do + +!$omp target teams distribute parallel do simd nowait +do i = 1, 5 +end do +!$omp end target teams distribute parallel do simd + +!$omp target simd nowait +do i = 1, 5 +end do +!$omp end target simd + +!$omp target teams nowait +!$omp end target teams + +!$omp target teams distribute nowait +do i = 1, 5 +end do +!$omp end target teams distribute + +!$omp target teams distribute simd nowait +do i = 1, 5 +end do +!$omp end target teams distribute simd + +!$omp target teams loop nowait +do i = 1, 5 +end do +!$omp end target teams loop + +!$omp workshare nowait +A(:) = 5 +!$omp end workshare +end + +! Note: internally, for '... parallel do ...', 'nowait' is always added +! such that for 'omp end target parallel do nowait', 'nowait' is on both +! 'target' as specified in the OpenMP spec and and on 'do' due to internal usage. + +! Expected with 'nowait' + +! { dg-final { scan-tree-dump-times "#pragma omp for nowait" 6 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp for schedule\\(static\\) nowait" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp sections nowait" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp single nowait" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp target nowait" 12 "original" } } + +! Never: + +! { dg-final { scan-tree-dump-not "#pragma omp distribute\[^\n\r]*nowait" "original" } } +! { dg-final { scan-tree-dump-not "#pragma omp loop\[^\n\r]*nowait" "original" } } +! { dg-final { scan-tree-dump-not "#pragma omp parallel\[^\n\r]*nowait" "original" } } +! { dg-final { scan-tree-dump-not "#pragma omp section\[^s\]\[^\n\r]*nowait" "original" } } +! { dg-final { scan-tree-dump-not "#pragma omp simd\[^\n\r]*nowait" "original" } } +! { dg-final { scan-tree-dump-not "#pragma omp teams\[^\n\r]*nowait" "original" } } + +! Sometimes or never with nowait: + +! { dg-final { scan-tree-dump-times "#pragma omp distribute\[\n\r]" 4 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp loop\[\n\r]" 2 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp parallel\[\n\r]" 6 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp section\[\n\r]" 1 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp simd linear\\(i:1\\)\[\n\r]" 5 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp teams\[\n\r]" 6 "original" } } + +! { dg-final { scan-tree-dump-times "#pragma omp target\[\n\r]" 0 "original" } } +! { dg-final { scan-tree-dump-times "#pragma omp for\[\n\r]" 0 "original" } } diff --git a/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90 b/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90 new file mode 100644 index 00000000000..5e666d123c5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/nowait-6.f90 @@ -0,0 +1,92 @@ +subroutine foo +implicit none +integer :: i, a(5) + +!$omp do nowait nowait ! { dg-error "Duplicated 'nowait' clause" } +do i = 1, 5 +end do + +!$omp do +do i = 1, 5 +end do +!$omp do nowait nowait ! { dg-error "Duplicated 'nowait' clause" } + +!$omp do nowait +do i = 1, 5 +end do +!$omp end do nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp do simd nowait +do i = 1, 5 +end do +!$omp end do simd nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp scope nowait +!$omp end scope nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp sections nowait + !$omp section + block; end block +!$omp end sections nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp single nowait +!$omp end single nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target nowait +!$omp end target nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target parallel nowait +!$omp end target parallel nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target parallel do nowait +do i = 1, 5 +end do +!$omp end target parallel do nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target parallel do simd nowait +do i = 1, 5 +end do +!$omp end target parallel do simd nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target parallel loop nowait +do i = 1, 5 +end do +!$omp end target parallel loop nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target teams distribute parallel do nowait +do i = 1, 5 +end do +!$omp end target teams distribute parallel do nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target teams distribute parallel do simd nowait +do i = 1, 5 +end do +!$omp end target teams distribute parallel do simd nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target simd nowait +do i = 1, 5 +end do +!$omp end target simd nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target teams nowait +!$omp end target teams nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target teams distribute nowait +do i = 1, 5 +end do +!$omp end target teams distribute nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target teams distribute simd nowait +do i = 1, 5 +end do +!$omp end target teams distribute simd nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp target teams loop nowait +do i = 1, 5 +end do +!$omp end target teams loop nowait ! { dg-error "Duplicated NOWAIT clause" } + +!$omp workshare nowait +A(:) = 5 +!$omp end workshare nowait ! { dg-error "Duplicated NOWAIT clause" } +end diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index 0f2998cf8f1..6d580f70b2b 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -360,7 +360,7 @@ to address of matching mapped list item per 5.1, Sect. 2.21.7.2 @tab N @tab @tab N @tab @item @code{omp}/@code{ompx}/@code{omx} sentinels and @code{omp_}/@code{ompx_} namespaces @tab N/A @tab -@item Clauses on @code{end} directive can be on directive @tab N @tab +@item Clauses on @code{end} directive can be on directive @tab Y @tab @item Deprecation of no-argument @code{destroy} clause on @code{depobj} @tab N @tab @item @code{linear} clause syntax changes and @code{step} modifier @tab Y @tab