From patchwork Fri Aug 26 18:21:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 57109 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D98CF3850217 for ; Fri, 26 Aug 2022 18:21:56 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id C691C3851151; Fri, 26 Aug 2022 18:21:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org C691C3851151 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com X-IronPort-AV: E=Sophos;i="5.93,265,1654588800"; d="diff'?scan'208";a="82076814" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 26 Aug 2022 10:21:34 -0800 IronPort-SDR: wT9AzjkR3oNKHstTMdk3Jmo1WrWvWr3KqURmuqD/D0vyu9K1S28pWnWyDGk2rdXwlBS9wntoKS hW7GdlXiV6x0dBbLG6T0InHNpgXs/vItX0tpRHSBfWqF0riQV6RFkK9Pb88Tn8JL/Ts1NqIIyj KEFRqwSyGCOAj0sPZudMFmqosAUAZc2doqEJugJamXUXBowk7Qeh6LaVAh2NJO1xxJsniQP62g 6ZIqEg5HLBMbmBlzDOBx4qx7iO1H6YNjfsAizc3GEMEB/bsu7EOAAruN0XdlLsPq8Xr5mAZQ3O n7I= Message-ID: <821786f3-ac7b-01e3-a386-f7c082494022@codesourcery.com> Date: Fri, 26 Aug 2022 20:21:26 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.0 Content-Language: en-US To: gcc-patches , Jakub Jelinek , fortran From: Tobias Burnus Subject: [Patch] OpenMP/Fortran: Permit end-clause on directive X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-12.mgc.mentorg.com (139.181.222.12) To svr-ies-mbx-12.mgc.mentorg.com (139.181.222.12) X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" I did run into some issues related to this; those turned out to be unrelated, but I end ended up implementing this feature. Side remark: 'omp parallel workshare' seems to actually permit 'nowait' now, but I guess that's an unintended change due to the syntax-representation change. Hence, it is now tracked as Spec Issue 3338 and I do not permit it. OK for mainline? Tobias ----------------- Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 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