From patchwork Fri Jul 24 09:00:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 1335517 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BCjpt4Hv6z9sRN for ; Fri, 24 Jul 2020 19:00:53 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E7272393BC0C; Fri, 24 Jul 2020 09:00:48 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa4.mentor.iphmx.com (esa4.mentor.iphmx.com [68.232.137.252]) by sourceware.org (Postfix) with ESMTPS id 7046F393B07D; Fri, 24 Jul 2020 09:00:45 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 7046F393B07D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=Tobias_Burnus@mentor.com IronPort-SDR: xorqIBr8XSWVVpDQEml+5axusPaxsznT1kypfBQHswoQ7i4ECYDoGTbsT+xceKN3HZlcefRkP9 1tdQxtEJ7tpkFMt+bqGvMq32DteE7Xq8eD6QUgdobOB4xlVi7cxcA7E8a/KaX4FcG5e5OiNuCx Wt+naXWEnoE+y2R61/uMuRIOsfQ3+oF3FfpDj5Ac9Bg8jhFLLB2rU85xY9zT8778CAPUNKgVDW VbYFHU3CBi0w9sonUYdRSwXOI/foAOqIzoW4AhWceUZgY7QyOA1BWl402pfVjUurh1+wS7vYiu gxg= X-IronPort-AV: E=Sophos;i="5.75,390,1589270400"; d="diff'?scan'208";a="51373634" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa4.mentor.iphmx.com with ESMTP; 24 Jul 2020 01:00:44 -0800 IronPort-SDR: N6RC1mjEUCcgH4e4pDhZDnPlgC4O1tscG0mcMMGI34+KNvFPXgbiRhRJD15zNGFFnIjQc9o/n1 Lp5Kxbwz/uCg/k9uIjWZysg0V5ECNNtz5txRauY7NV33OcXYQEL+cIa4VKYyJV/S+3rhuvI6Pq sekRt1bMbKPPV89MghQIaWMUchIEPyl/svpfYeib+RBmQSOiTGJo+fAoyTLSYxEGto5Q1klaFT 4KierrzurPEJ/UFOPbd1duNq23QOvuwNFmV42WXybcNRN/v9DV+WjNNebUfO+Z66pTyUkcK0I9 Y/Q= To: gcc-patches , fortran , Jakub Jelinek From: Tobias Burnus Subject: [Patch] OpenMP: Add 'omp requires' to Fortran (mostly parsing) Message-ID: <03601efc-b586-d58e-5950-3cfb40081d1a@codesourcery.com> Date: Fri, 24 Jul 2020 11:00:37 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 Content-Language: en-US X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-04.mgc.mentorg.com (139.181.222.4) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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@gcc.gnu.org Sender: "Gcc-patches" As with C/C++, the offloading requires are not implemented an rejected early with a 'sorry'. The mem-setting default for atomic is handled, but only 'seq_cst' as currently gfortran's only supports this one. (C/C++ support more.) In C/C++, the 'requires' has to be at file scope. For Fortran, "must appear in the specification part of a program unit," which is: "A program unit is a main program, an external subprogram, a module, a submodule, or a block data program unit." For the atomic setting, one has: At most one requires directive with atomic_default_mem_order clause can appear in a single compilation unit. For the offloading settings + dynamic_allocators, I do not see this restriction, i.e. I guess one can specify it multiple times. However, there are the restrictions: A requires directive with a unified_address, unified_shared_memory, or reverse_offload clause must appear lexically before any device constructs or device routines. (i.e. not: dynamic_allocators) The requires directive with atomic_default_mem_order clause may not appear lexically after any atomic construct on which memory-order-clause is not specified. I do wonder whether the following should be permitted: subroutine one !$omp requires unified_shared_memory !$omp target ... subroutine two !$omp requires unified_shared_memory !$omp target which conceptually in terms of Fortran makes sense, but is currently not permitted (in the patch). On the other hand, for larger modern code, code is usually in a module and there is one module per file. I am not sure whether it makes sense to store the offloading requires also in a module – and what to do on 'use'; the patch currently does not do this. OK? Tobias ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter OpenMP: Add 'omp requires' to Fortran (mostly parsing) gcc/fortran/ChangeLog: * gfortran.h (enum gfc_statement): Add ST_OMP_REQUIRES. (enum gfc_omp_requires_kind): New. (gfc_omp_requires, gfc_seen_omp_target, gfc_seen_omp_atomic_wo_memorder): New global vars. * match.h (gfc_match_omp_requires): New. * openmp.c (gfc_omp_requires, gfc_seen_omp_target, gfc_seen_omp_atomic_wo_memorder): New global vars. (gfc_match_omp_requires): New function. (gfc_match_omp_oacc_atomic): Set gfc_seen_omp_atomic_wo_memorder. * parse.c (decode_omp_directive): Parse 'omp requires', set gfc_seen_omp_target. (gfc_ascii_statement): Handle ST_OMP_REQUIRES. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/requires-1.f90: New test. * gfortran.dg/gomp/requires-2.f90: New test. * gfortran.dg/gomp/requires-3.f90: New test. * gfortran.dg/gomp/requires-4.f90: New test. * gfortran.dg/gomp/requires-5.f90: New test. * gfortran.dg/gomp/requires-6.f90: New test. * gfortran.dg/gomp/requires-7.f90: New test. gcc/fortran/gfortran.h | 20 +++- gcc/fortran/match.h | 1 + gcc/fortran/openmp.c | 157 ++++++++++++++++++++++++++ gcc/fortran/parse.c | 31 ++++- gcc/testsuite/gfortran.dg/gomp/requires-1.f90 | 13 +++ gcc/testsuite/gfortran.dg/gomp/requires-2.f90 | 12 ++ gcc/testsuite/gfortran.dg/gomp/requires-3.f90 | 4 + gcc/testsuite/gfortran.dg/gomp/requires-4.f90 | 20 ++++ gcc/testsuite/gfortran.dg/gomp/requires-5.f90 | 14 +++ gcc/testsuite/gfortran.dg/gomp/requires-6.f90 | 10 ++ gcc/testsuite/gfortran.dg/gomp/requires-7.f90 | 41 +++++++ 11 files changed, 321 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 5fa86aa4e30..007cfe596d5 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -263,7 +263,7 @@ enum gfc_statement ST_OMP_TARGET_SIMD, ST_OMP_END_TARGET_SIMD, ST_OMP_TASKLOOP, ST_OMP_END_TASKLOOP, ST_OMP_TASKLOOP_SIMD, ST_OMP_END_TASKLOOP_SIMD, ST_OMP_ORDERED_DEPEND, - ST_PROCEDURE, ST_GENERIC, ST_CRITICAL, ST_END_CRITICAL, + ST_OMP_REQUIRES, ST_PROCEDURE, ST_GENERIC, ST_CRITICAL, ST_END_CRITICAL, ST_GET_FCN_CHARACTERISTICS, ST_LOCK, ST_UNLOCK, ST_EVENT_POST, ST_EVENT_WAIT, ST_FAIL_IMAGE, ST_FORM_TEAM, ST_CHANGE_TEAM, ST_END_TEAM, ST_SYNC_TEAM, ST_NONE @@ -1334,6 +1334,20 @@ enum gfc_omp_if_kind OMP_IF_LAST }; +enum gfc_omp_requires_kind +{ + OMP_REQ_REVERSE_OFFLOAD = (1 << 0), + OMP_REQ_UNIFIED_ADDRESS = (1 << 1), + OMP_REQ_UNIFIED_SHARED_MEMORY = (1 << 2), + OMP_REQ_DYNAMIC_ALLOCATORS = (1 << 3), + OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST = (1 << 4), + OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL = (1 << 5), + OMP_REQ_ATOMIC_MEM_ORDER_RELAXED = (1 << 6), + OMP_REQ_ATOMIC_MEM_ORDER_MASK = (OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST + | OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL + | OMP_REQ_ATOMIC_MEM_ORDER_RELAXED) +}; + typedef struct gfc_omp_clauses { struct gfc_expr *if_expr; @@ -3269,6 +3283,10 @@ void gfc_free_case_list (gfc_case *); gfc_expr *gfc_get_parentheses (gfc_expr *); /* openmp.c */ +extern int gfc_omp_requires; +extern bool gfc_seen_omp_target; +extern bool gfc_seen_omp_atomic_wo_memorder; + struct gfc_omp_saved_state { void *ptrs[2]; int ints[1]; }; void gfc_free_omp_clauses (gfc_omp_clauses *); void gfc_free_oacc_declare_clauses (struct gfc_oacc_declare *); diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index b3fb7033891..7bf70d77016 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -177,6 +177,7 @@ match gfc_match_omp_parallel_do (void); match gfc_match_omp_parallel_do_simd (void); match gfc_match_omp_parallel_sections (void); match gfc_match_omp_parallel_workshare (void); +match gfc_match_omp_requires (void); match gfc_match_omp_sections (void); match gfc_match_omp_simd (void); match gfc_match_omp_single (void); diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index f8f2439b6e4..3748734392a 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -28,6 +28,9 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "gomp-constants.h" +int gfc_omp_requires = 0; +bool gfc_seen_omp_target = false, gfc_seen_omp_atomic_wo_memorder = false; + /* Match an end of OpenMP directive. End of OpenMP directive is optional whitespace, followed by '\n' or comment '!'. */ @@ -3424,6 +3427,158 @@ gfc_match_omp_parallel_workshare (void) return match_omp (EXEC_OMP_PARALLEL_WORKSHARE, OMP_PARALLEL_CLAUSES); } +match +gfc_match_omp_requires (void) +{ + static const char *clauses[] = {"reverse_offload", + "unified_address", + "unified_shared_memory", + "dynamic_allocators", + "atomic_default"}; + const char *clause = NULL; + int requires_clauses = 0; + bool first = true; + locus old_loc; + + if (gfc_current_ns->parent) + { + gfc_error ("!$OMP REQUIRES at %C must appear in the specification part " + "of a program unit"); + return MATCH_ERROR; + } + + while (true) + { + old_loc = gfc_current_locus; + int requires_clause = 0; + if ((first || gfc_match_char (',') != MATCH_YES) + && (first && gfc_match_space () != MATCH_YES)) + goto error; + first = false; + gfc_gobble_whitespace (); + old_loc = gfc_current_locus; + + if (gfc_match_omp_eos () != MATCH_NO) + break; + if (gfc_match (clauses[0]) == MATCH_YES) + { + clause = clauses[0]; + requires_clause = (int) OMP_REQ_REVERSE_OFFLOAD; + if (requires_clauses & (int) OMP_REQ_REVERSE_OFFLOAD) + goto duplicate_clause; + if (gfc_seen_omp_target) + goto requires_after_target; + if (gfc_omp_requires & (int) OMP_REQ_REVERSE_OFFLOAD) + goto next; + } + else if (gfc_match (clauses[1]) == MATCH_YES) + { + clause = clauses[1]; + requires_clause = (int) OMP_REQ_UNIFIED_ADDRESS; + if (requires_clauses & (int) OMP_REQ_UNIFIED_ADDRESS) + goto duplicate_clause; + if (gfc_seen_omp_target) + goto requires_after_target; + if (gfc_omp_requires & (int) OMP_REQ_UNIFIED_ADDRESS) + goto next; + } + else if (gfc_match (clauses[2]) == MATCH_YES) + { + clause = clauses[2]; + requires_clause = (int) OMP_REQ_UNIFIED_SHARED_MEMORY; + if (requires_clauses & (int) OMP_REQ_UNIFIED_SHARED_MEMORY) + goto duplicate_clause; + if (gfc_seen_omp_target) + goto requires_after_target; + if (gfc_omp_requires & (int) OMP_REQ_UNIFIED_SHARED_MEMORY) + goto next; + } + else if (gfc_match (clauses[3]) == MATCH_YES) + { + clause = clauses[3]; + requires_clause = (int) OMP_REQ_DYNAMIC_ALLOCATORS; + if (requires_clauses & (int) OMP_REQ_DYNAMIC_ALLOCATORS) + goto duplicate_clause; + if (gfc_omp_requires & (int) OMP_REQ_DYNAMIC_ALLOCATORS) + goto next; + } + else if (gfc_match ("atomic_default_mem_order (") == MATCH_YES) + { + clause = clauses[4]; + if (requires_clauses & OMP_REQ_ATOMIC_MEM_ORDER_MASK) + goto duplicate_clause; + if (gfc_match (" seq_cst )") == MATCH_YES) + requires_clause = (int) OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST; + else if (gfc_match (" acq_rel )") == MATCH_YES) + requires_clause = (int) OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL; + else if (gfc_match (" relaxed )") == MATCH_YES) + requires_clause = (int) OMP_REQ_ATOMIC_MEM_ORDER_RELAXED; + else + { + gfc_error ("Expected SEQ_CST, ACQ_REL or RELAXED for " + "ATOMIC_DEFAULT_MEM_ORDER clause at %C"); + goto error; + } + if ((gfc_omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) + && ((gfc_omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) + != (requires_clause & OMP_REQ_ATOMIC_MEM_ORDER_MASK))) + { + gfc_error ("ATOMIC_DEFAULT_MEM_ORDER clause at %L " + "specified with different value than previously " + "in the same translation unit", &old_loc); + goto error; + } + if (gfc_omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) + { + gfc_error ("Only one ATOMIC_DEFAULT_MEM_ORDER clause such as at " + "%L per translation unit permitted", &old_loc); + goto error; + } + if (gfc_seen_omp_atomic_wo_memorder) + { + gfc_error ("OMP REQUIRES with ATOMIC_DEFAULT_MEM_ORDER clause at " + "%L specified after first use of an OMP ATOMIC which " + "uses the default-memory order", &old_loc); + goto error; + } + /* TODO: Middle-end support exists, but not yet FE support. */ + if (requires_clause != OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST) + gfc_error_now ("Sorry, only SEQ_CST is currently supported for the " + "ATOMIC_DEFAULT_MEM_ORDER clause at %L on the " + "REQUIRES directive", &old_loc); + } + else + goto error; +next: + requires_clauses |= requires_clause; + if (requires_clause & ~((int) OMP_REQ_ATOMIC_MEM_ORDER_MASK)) + gfc_error_now ("Sorry, %qs clause at %L on REQUIRES directive is not " + "yet supported", clause, &old_loc); + } + + gfc_omp_requires |= requires_clauses; + if (requires_clauses == 0) + { + if (!gfc_error_flag_test ()) + gfc_error ("Clause expected at %C"); + goto error; + } + return MATCH_YES; + +requires_after_target: + gfc_error ("Clause %qs at %L specified after a device construct/routine", + clause, &old_loc); + goto error; +duplicate_clause: + gfc_error ("%qs clause at %L specified more than once", clause, &old_loc); +error: + if (!gfc_error_flag_test ()) + gfc_error ("Expected UNIFIED_ADDRESS, UNIFIED_SHARED_MEMORY, " + "DYNAMIC_ALLOCATORS, REVERSE_OFFLOAD, or " + "ATOMIC_DEFAULT_MEM_ORDER clause at %L", &old_loc); + return MATCH_ERROR; +} + match gfc_match_omp_sections (void) @@ -3745,6 +3900,8 @@ gfc_match_omp_oacc_atomic (bool omp_p) new_st.op = (omp_p ? EXEC_OMP_ATOMIC : EXEC_OACC_ATOMIC); if (seq_cst) op = (gfc_omp_atomic_op) (op | GFC_OMP_ATOMIC_SEQ_CST); + else + gfc_seen_omp_atomic_wo_memorder = true; new_st.ext.omp_atomic = op; return MATCH_YES; } diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 96fd4aaee5e..6d200da2f1c 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -995,6 +995,9 @@ decode_omp_directive (void) ST_OMP_PARALLEL_WORKSHARE); matcho ("parallel", gfc_match_omp_parallel, ST_OMP_PARALLEL); break; + case 'r': + matcho ("requires", gfc_match_omp_requires, ST_OMP_REQUIRES); + break; case 's': matcho ("sections", gfc_match_omp_sections, ST_OMP_SECTIONS); matcho ("section", gfc_match_omp_eos_error, ST_OMP_SECTION); @@ -1086,6 +1089,28 @@ decode_omp_directive (void) return ST_NONE; } } + switch (ret) + { + case ST_OMP_DECLARE_TARGET: + case ST_OMP_TARGET: + case ST_OMP_TARGET_DATA: + case ST_OMP_TARGET_ENTER_DATA: + case ST_OMP_TARGET_EXIT_DATA: + case ST_OMP_TARGET_TEAMS: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case ST_OMP_TARGET_PARALLEL: + case ST_OMP_TARGET_PARALLEL_DO: + case ST_OMP_TARGET_PARALLEL_DO_SIMD: + case ST_OMP_TARGET_SIMD: + case ST_OMP_TARGET_UPDATE: + gfc_seen_omp_target = true; + break; + default: + break; + } return ret; do_spec_only: @@ -1604,7 +1629,8 @@ next_statement (void) /* OpenMP declaration statements. */ #define case_omp_decl case ST_OMP_THREADPRIVATE: case ST_OMP_DECLARE_SIMD: \ - case ST_OMP_DECLARE_TARGET: case ST_OMP_DECLARE_REDUCTION + case ST_OMP_DECLARE_TARGET: case ST_OMP_DECLARE_REDUCTION: \ + case ST_OMP_REQUIRES /* Block end statements. Errors associated with interchanging these are detected in gfc_match_end(). */ @@ -2407,6 +2433,9 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_PARALLEL_WORKSHARE: p = "!$OMP PARALLEL WORKSHARE"; break; + case ST_OMP_REQUIRES: + p = "!$OMP REQUIRES"; + break; case ST_OMP_SECTIONS: p = "!$OMP SECTIONS"; break; diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-1.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-1.f90 new file mode 100644 index 00000000000..b115a654e71 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-1.f90 @@ -0,0 +1,13 @@ +subroutine foo +!$omp requires unified_address +!$omp requires unified_shared_memory +!$omp requires unified_shared_memory unified_address +!$omp requires dynamic_allocators,reverse_offload +end + +subroutine bar +!$omp requires unified_shared_memory unified_address +!$omp requires atomic_default_mem_order(seq_cst) +end + +! { dg-prune-output "not yet supported" } diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-2.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-2.f90 new file mode 100644 index 00000000000..26ff019e986 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-2.f90 @@ -0,0 +1,12 @@ +!$omp requires ! { dg-error "Clause expected" } +!$omp requires unified_shared_memory,unified_shared_memory ! { dg-error "specified more than once" } +!$omp requires unified_address unified_address ! { dg-error "specified more than once" } +!$omp requires reverse_offload reverse_offload ! { dg-error "specified more than once" } +!$omp requires foobarbaz ! { dg-error "Expected UNIFIED_ADDRESS, UNIFIED_SHARED_MEMORY, DYNAMIC_ALLOCATORS, REVERSE_OFFLOAD, or ATOMIC_DEFAULT_MEM_ORDER clause" } +!$omp requires dynamic_allocators , dynamic_allocators ! { dg-error "specified more than once" } +!$omp requires atomic_default_mem_order(seq_cst) atomic_default_mem_order(seq_cst) ! { dg-error "specified more than once" } +!$omp requires atomic_default_mem_order (seq_cst) +!$omp requires atomic_default_mem_order (seq_cst) ! { dg-error "Only one ATOMIC_DEFAULT_MEM_ORDER clause such as at .1. per translation unit permitted" } +end + +! { dg-prune-output "not yet supported" } diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-3.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-3.f90 new file mode 100644 index 00000000000..4429aab2ee6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-3.f90 @@ -0,0 +1,4 @@ +!$omp requires atomic_default_mem_order(acquire) ! { dg-error "Expected SEQ_CST, ACQ_REL or RELAXED for ATOMIC_DEFAULT_MEM_ORDER clause" } +!$omp requires atomic_default_mem_order(release) ! { dg-error "Expected SEQ_CST, ACQ_REL or RELAXED for ATOMIC_DEFAULT_MEM_ORDER clause" } +!$omp requires atomic_default_mem_order(foobar) ! { dg-error "Expected SEQ_CST, ACQ_REL or RELAXED for ATOMIC_DEFAULT_MEM_ORDER clause" } +end diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-4.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-4.f90 new file mode 100644 index 00000000000..d7af86905d3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-4.f90 @@ -0,0 +1,20 @@ +subroutine bar +!$omp requires unified_shared_memory,unified_address,reverse_offload +end + +subroutine foo + !$omp target + !$omp end target +end + +subroutine foobar +i = 5 ! < execution statement +!$omp requires atomic_default_mem_order(seq_cst) ! { dg-error "Unexpected ..OMP REQUIRES statement" } +end + +!$omp requires dynamic_allocators ! OK +!$omp requires unified_shared_memory ! { dg-error "specified after a device construct/routine" } +!$omp requires unified_address ! { dg-error "specified after a device construct/routine" } +!$omp requires reverse_offload ! { dg-error "specified after a device construct/routine" } +end +! { dg-prune-output "not yet supported" } diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-5.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-5.f90 new file mode 100644 index 00000000000..8b85e236f8a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-5.f90 @@ -0,0 +1,14 @@ +subroutine bar +!$omp requires atomic_default_mem_order(seq_cst) +!$omp requires unified_shared_memory +end + +subroutine foo +!$omp requires unified_shared_memory +!$omp requires atomic_default_mem_order(relaxed) ! { dg-error "specified with different value than previously in the same translation unit" } +!$omp requires atomic_default_mem_order(seq_cst) ! { dg-error "Only one ATOMIC_DEFAULT_MEM_ORDER clause such as at .1. per translation unit permitted" } + !$omp target + !$omp end target +end + +! { dg-prune-output "not yet supported" } diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-6.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-6.f90 new file mode 100644 index 00000000000..00326e0be4d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-6.f90 @@ -0,0 +1,10 @@ +subroutine bar +!$omp atomic + i = i + 5 +end + +subroutine foo +!$omp requires atomic_default_mem_order(seq_cst) ! { dg-error "specified after first use of an OMP ATOMIC which uses the default-memory order" } +end + +! { dg-prune-output "not yet supported" } diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-7.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-7.f90 new file mode 100644 index 00000000000..3d75b89e00b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-7.f90 @@ -0,0 +1,41 @@ +subroutine bar2 + block + !$omp requires unified_shared_memory ! { dg-error "must appear in the specification part of a program unit" } + end block +end + +subroutine bar +contains + subroutine foo + !$omp requires unified_shared_memory ! { dg-error "must appear in the specification part of a program unit" } + end +end + +module m +contains + subroutine foo + !$omp requires unified_shared_memory ! { dg-error "must appear in the specification part of a program unit" } + end +end + +module m2 + interface + module subroutine foo() + end + end interface +end + +submodule (m2) m2_sub + !$omp requires unified_shared_memory +contains + module procedure foo + end +end + +program main +contains + subroutine foo + !$omp requires unified_shared_memory ! { dg-error "must appear in the specification part of a program unit" } + end +end +! { dg-prune-output "not yet supported" }