OpenMP: Support acquires/release in 'omp require atomic_default_mem_order' This is an OpenMP 5.2 feature. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_requires): Handle acquires/release in atomic_default_mem_order clause. (c_parser_omp_atomic): Update. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_requires): Handle acquires/release in atomic_default_mem_order clause. (cp_parser_omp_atomic): Update. gcc/fortran/ChangeLog: * gfortran.h (enum gfc_omp_requires_kind): Add OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE and OMP_REQ_ATOMIC_MEM_ORDER_RELEASE. (gfc_namespace): Add a 7th bit to omp_requires. * module.cc (enum ab_attribute): Add AB_OMP_REQ_MEM_ORDER_ACQUIRE and AB_OMP_REQ_MEM_ORDER_RELEASE (mio_symbol_attribute): Handle it. * openmp.cc (gfc_omp_requires_add_clause): Update for acquire/release. (gfc_match_omp_requires): Likewise. (gfc_match_omp_atomic): Handle them for atomic_default_mem_order. * parse.cc: Likewise. gcc/testsuite/ChangeLog: * c-c++-common/gomp/requires-3.c: Update for now valid code. * gfortran.dg/gomp/requires-3.f90: Likewise. * gfortran.dg/gomp/requires-2.f90: Update dg-error. * gfortran.dg/gomp/requires-5.f90: Likewise. * c-c++-common/gomp/requires-5.c: New test. * c-c++-common/gomp/requires-6.c: New test. * c-c++-common/gomp/requires-7.c: New test. * c-c++-common/gomp/requires-8.c: New test. * gfortran.dg/gomp/requires-10.f90: New test. * gfortran.dg/gomp/requires-11.f90: New test. gcc/c/c-parser.cc | 32 +++++++++++++++- gcc/cp/parser.cc | 32 +++++++++++++++- gcc/fortran/gfortran.h | 22 ++++++----- gcc/fortran/module.cc | 19 +++++++++ gcc/fortran/openmp.cc | 53 +++++++++++++++++++++----- gcc/fortran/parse.cc | 8 ++++ gcc/testsuite/c-c++-common/gomp/requires-3.c | 8 ++-- gcc/testsuite/c-c++-common/gomp/requires-5.c | 23 +++++++++++ gcc/testsuite/c-c++-common/gomp/requires-6.c | 23 +++++++++++ gcc/testsuite/c-c++-common/gomp/requires-7.c | 11 ++++++ gcc/testsuite/c-c++-common/gomp/requires-8.c | 14 +++++++ gcc/testsuite/gfortran.dg/gomp/requires-10.f90 | 36 +++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/requires-11.f90 | 31 +++++++++++++++ gcc/testsuite/gfortran.dg/gomp/requires-2.f90 | 2 +- gcc/testsuite/gfortran.dg/gomp/requires-3.f90 | 7 ++-- gcc/testsuite/gfortran.dg/gomp/requires-5.f90 | 2 +- 16 files changed, 291 insertions(+), 32 deletions(-) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index df9a07928b5..5700ccccc49 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -20896,6 +20896,28 @@ c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc) case OMP_MEMORY_ORDER_SEQ_CST: memory_order = OMP_MEMORY_ORDER_SEQ_CST; break; + case OMP_MEMORY_ORDER_ACQUIRE: + if (code == NOP_EXPR) /* atomic write */ + { + error_at (loc, "%<#pragma omp atomic write%> incompatible with " + "% clause implicitly provided by a " + "% directive"); + memory_order = OMP_MEMORY_ORDER_SEQ_CST; + } + else + memory_order = OMP_MEMORY_ORDER_ACQUIRE; + break; + case OMP_MEMORY_ORDER_RELEASE: + if (code == OMP_ATOMIC_READ) + { + error_at (loc, "%<#pragma omp atomic read%> incompatible with " + "% clause implicitly provided by a " + "% directive"); + memory_order = OMP_MEMORY_ORDER_SEQ_CST; + } + else + memory_order = OMP_MEMORY_ORDER_RELEASE; + break; case OMP_MEMORY_ORDER_ACQ_REL: switch (code) { @@ -25724,15 +25746,21 @@ c_parser_omp_requires (c_parser *parser) else if (!strcmp (p, "relaxed")) this_req = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED; + else if (!strcmp (p, "release")) + this_req + = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE; else if (!strcmp (p, "acq_rel")) this_req = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL; + else if (!strcmp (p, "acquire")) + this_req + = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE; } if (this_req == 0) { error_at (c_parser_peek_token (parser)->location, - "expected %, % or " - "%"); + "expected %, %, " + "%, % or %"); switch (c_parser_peek_token (parser)->type) { case CPP_EOF: diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 2464d1a0783..93bd7f112a2 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -42436,6 +42436,28 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok, bool openacc) case OMP_MEMORY_ORDER_SEQ_CST: memory_order = OMP_MEMORY_ORDER_SEQ_CST; break; + case OMP_MEMORY_ORDER_ACQUIRE: + if (code == NOP_EXPR) /* atomic write */ + { + error_at (loc, "%<#pragma omp atomic write%> incompatible with " + "% clause implicitly provided by a " + "% directive"); + memory_order = OMP_MEMORY_ORDER_SEQ_CST; + } + else + memory_order = OMP_MEMORY_ORDER_ACQUIRE; + break; + case OMP_MEMORY_ORDER_RELEASE: + if (code == OMP_ATOMIC_READ) + { + error_at (loc, "%<#pragma omp atomic read%> incompatible with " + "% clause implicitly provided by a " + "% directive"); + memory_order = OMP_MEMORY_ORDER_SEQ_CST; + } + else + memory_order = OMP_MEMORY_ORDER_RELEASE; + break; case OMP_MEMORY_ORDER_ACQ_REL: switch (code) { @@ -49126,15 +49148,21 @@ cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok) else if (!strcmp (p, "relaxed")) this_req = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED; + else if (!strcmp (p, "release")) + this_req + = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE; else if (!strcmp (p, "acq_rel")) this_req = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL; + else if (!strcmp (p, "acquire")) + this_req + = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE; } if (this_req == 0) { error_at (cp_lexer_peek_token (parser->lexer)->location, - "expected %, % or " - "%"); + "expected %, %, " + "%, % or %"); switch (cp_lexer_peek_token (parser->lexer)->type) { case CPP_EOF: diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index aa3f6cb70b4..5477c3d2966 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1496,19 +1496,23 @@ enum gfc_omp_atomic_op enum gfc_omp_requires_kind { /* Keep in sync with gfc_namespace, esp. with omp_req_mem_order. */ - OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST = 1, /* 01 */ - OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL = 2, /* 10 */ - OMP_REQ_ATOMIC_MEM_ORDER_RELAXED = 3, /* 11 */ - OMP_REQ_REVERSE_OFFLOAD = (1 << 2), - OMP_REQ_UNIFIED_ADDRESS = (1 << 3), - OMP_REQ_UNIFIED_SHARED_MEMORY = (1 << 4), - OMP_REQ_DYNAMIC_ALLOCATORS = (1 << 5), + OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST = 1, /* 001 */ + OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL = 2, /* 010 */ + OMP_REQ_ATOMIC_MEM_ORDER_RELAXED = 3, /* 011 */ + OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE = 4, /* 100 */ + OMP_REQ_ATOMIC_MEM_ORDER_RELEASE = 5, /* 101 */ + OMP_REQ_REVERSE_OFFLOAD = (1 << 3), + OMP_REQ_UNIFIED_ADDRESS = (1 << 4), + OMP_REQ_UNIFIED_SHARED_MEMORY = (1 << 5), + OMP_REQ_DYNAMIC_ALLOCATORS = (1 << 6), OMP_REQ_TARGET_MASK = (OMP_REQ_REVERSE_OFFLOAD | OMP_REQ_UNIFIED_ADDRESS | OMP_REQ_UNIFIED_SHARED_MEMORY), 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) + | OMP_REQ_ATOMIC_MEM_ORDER_RELAXED + | OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE + | OMP_REQ_ATOMIC_MEM_ORDER_RELEASE) }; enum gfc_omp_memorder @@ -2257,7 +2261,7 @@ typedef struct gfc_namespace unsigned implicit_interface_calls:1; /* OpenMP requires. */ - unsigned omp_requires:6; + unsigned omp_requires:7; unsigned omp_target_seen:1; /* Set to 1 if this is an implicit OMP structured block. */ diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc index c07e9dc9ba2..3c07818e2cf 100644 --- a/gcc/fortran/module.cc +++ b/gcc/fortran/module.cc @@ -2093,6 +2093,7 @@ enum ab_attribute AB_OMP_REQ_REVERSE_OFFLOAD, AB_OMP_REQ_UNIFIED_ADDRESS, AB_OMP_REQ_UNIFIED_SHARED_MEMORY, AB_OMP_REQ_DYNAMIC_ALLOCATORS, AB_OMP_REQ_MEM_ORDER_SEQ_CST, AB_OMP_REQ_MEM_ORDER_ACQ_REL, + AB_OMP_REQ_MEM_ORDER_ACQUIRE, AB_OMP_REQ_MEM_ORDER_RELEASE, AB_OMP_REQ_MEM_ORDER_RELAXED, AB_OMP_DEVICE_TYPE_NOHOST, AB_OMP_DEVICE_TYPE_HOST, AB_OMP_DEVICE_TYPE_ANY }; @@ -2175,7 +2176,9 @@ static const mstring attr_bits[] = minit ("OMP_REQ_DYNAMIC_ALLOCATORS", AB_OMP_REQ_DYNAMIC_ALLOCATORS), minit ("OMP_REQ_MEM_ORDER_SEQ_CST", AB_OMP_REQ_MEM_ORDER_SEQ_CST), minit ("OMP_REQ_MEM_ORDER_ACQ_REL", AB_OMP_REQ_MEM_ORDER_ACQ_REL), + minit ("OMP_REQ_MEM_ORDER_ACQUIRE", AB_OMP_REQ_MEM_ORDER_ACQUIRE), minit ("OMP_REQ_MEM_ORDER_RELAXED", AB_OMP_REQ_MEM_ORDER_RELAXED), + minit ("OMP_REQ_MEM_ORDER_RELEASE", AB_OMP_REQ_MEM_ORDER_RELEASE), minit ("OMP_DEVICE_TYPE_HOST", AB_OMP_DEVICE_TYPE_HOST), minit ("OMP_DEVICE_TYPE_NOHOST", AB_OMP_DEVICE_TYPE_NOHOST), minit ("OMP_DEVICE_TYPE_ANYHOST", AB_OMP_DEVICE_TYPE_ANY), @@ -2442,9 +2445,15 @@ mio_symbol_attribute (symbol_attribute *attr) if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) == OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL) MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_ACQ_REL, attr_bits); + if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) + == OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE) + MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_ACQUIRE, attr_bits); if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) == OMP_REQ_ATOMIC_MEM_ORDER_RELAXED) MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_RELAXED, attr_bits); + if ((gfc_current_ns->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) + == OMP_REQ_ATOMIC_MEM_ORDER_RELEASE) + MIO_NAME (ab_attribute) (AB_OMP_REQ_MEM_ORDER_RELEASE, attr_bits); } switch (attr->omp_device_type) { @@ -2724,11 +2733,21 @@ mio_symbol_attribute (symbol_attribute *attr) "acq_rel", &gfc_current_locus, module_name); break; + case AB_OMP_REQ_MEM_ORDER_ACQUIRE: + gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE, + "acquires", &gfc_current_locus, + module_name); + break; case AB_OMP_REQ_MEM_ORDER_RELAXED: gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_RELAXED, "relaxed", &gfc_current_locus, module_name); break; + case AB_OMP_REQ_MEM_ORDER_RELEASE: + gfc_omp_requires_add_clause (OMP_REQ_ATOMIC_MEM_ORDER_RELEASE, + "release", &gfc_current_locus, + module_name); + break; case AB_OMP_DEVICE_TYPE_HOST: attr->omp_device_type = OMP_DEVICE_TYPE_HOST; break; diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 794df19a4d1..19995708c23 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -6251,14 +6251,15 @@ gfc_omp_requires_add_clause (gfc_omp_requires_kind clause, != (int) clause) { const char *other; - if (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST) - other = "seq_cst"; - else if (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL) - other = "acq_rel"; - else if (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_RELAXED) - other = "relaxed"; - else - gcc_unreachable (); + switch (prog_unit->omp_requires & OMP_REQ_ATOMIC_MEM_ORDER_MASK) + { + case OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST: other = "seq_cst"; break; + case OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL: other = "acq_rel"; break; + case OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE: other = "acquire"; break; + case OMP_REQ_ATOMIC_MEM_ORDER_RELAXED: other = "relaxed"; break; + case OMP_REQ_ATOMIC_MEM_ORDER_RELEASE: other = "release"; break; + default: gcc_unreachable (); + } if (module_name) gfc_error ("!$OMP REQUIRES clause % " @@ -6372,15 +6373,25 @@ gfc_match_omp_requires (void) clause = "acq_rel"; requires_clause = OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL; } + else if (gfc_match (" acquire )") == MATCH_YES) + { + clause = "acquire"; + requires_clause = OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE; + } else if (gfc_match (" relaxed )") == MATCH_YES) { clause = "relaxed"; requires_clause = OMP_REQ_ATOMIC_MEM_ORDER_RELAXED; } + else if (gfc_match (" release )") == MATCH_YES) + { + clause = "release"; + requires_clause = OMP_REQ_ATOMIC_MEM_ORDER_RELEASE; + } else { - gfc_error ("Expected SEQ_CST, ACQ_REL or RELAXED for " - "ATOMIC_DEFAULT_MEM_ORDER clause at %C"); + gfc_error ("Expected ACQ_REL, ACQUIRE, RELAXED, RELEASE or " + "SEQ_CST for ATOMIC_DEFAULT_MEM_ORDER clause at %C"); goto error; } } @@ -6827,6 +6838,28 @@ gfc_match_omp_atomic (void) else c->memorder = OMP_MEMORDER_RELEASE; break; + case OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE: + if (c->atomic_op == GFC_OMP_ATOMIC_WRITE) + { + gfc_error ("!$OMP ATOMIC WRITE at %L incompatible with " + "ACQUIRES clause implicitly provided by a " + "REQUIRES directive", &loc); + c->memorder = OMP_MEMORDER_SEQ_CST; + } + else + c->memorder = OMP_MEMORDER_ACQUIRE; + break; + case OMP_REQ_ATOMIC_MEM_ORDER_RELEASE: + if (c->atomic_op == GFC_OMP_ATOMIC_READ) + { + gfc_error ("!$OMP ATOMIC READ at %L incompatible with " + "RELEASE clause implicitly provided by a " + "REQUIRES directive", &loc); + c->memorder = OMP_MEMORDER_SEQ_CST; + } + else + c->memorder = OMP_MEMORDER_RELEASE; + break; default: gcc_unreachable (); } diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index abd3a424f38..c0e80b1a9c3 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -7269,10 +7269,18 @@ done: omp_requires_mask = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_ACQ_REL); break; + case OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE: + omp_requires_mask + = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_ACQUIRE); + break; case OMP_REQ_ATOMIC_MEM_ORDER_RELAXED: omp_requires_mask = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_RELAXED); break; + case OMP_REQ_ATOMIC_MEM_ORDER_RELEASE: + omp_requires_mask + = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_RELEASE); + break; } if (omp_target_seen) diff --git a/gcc/testsuite/c-c++-common/gomp/requires-3.c b/gcc/testsuite/c-c++-common/gomp/requires-3.c index bd2479ba8ff..2fd601acefa 100644 --- a/gcc/testsuite/c-c++-common/gomp/requires-3.c +++ b/gcc/testsuite/c-c++-common/gomp/requires-3.c @@ -1,6 +1,6 @@ -#pragma omp requires atomic_default_mem_order(acquire) /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */ -#pragma omp requires atomic_default_mem_order(release) /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */ -#pragma omp requires atomic_default_mem_order(foobar) /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */ -#pragma omp requires atomic_default_mem_order ( /* { dg-error "expected 'seq_cst', 'relaxed' or 'acq_rel'" } */ +#pragma omp requires atomic_default_mem_order(foobar) /* { dg-error "expected 'acq_rel', 'acquire', 'relaxed', 'release' or 'seq_cst'" } */ +#pragma omp requires atomic_default_mem_order ( /* { dg-error "expected 'acq_rel', 'acquire', 'relaxed', 'release' or 'seq_cst'" } */ /* { dg-error "expected '\\\)' before end of line" "" { target *-*-* } .-1 } */ #pragma omp requires atomic_default_mem_order(seq_cst), /* { dg-error "expected end of line before ',' token" } */ +/* Valid since since 5.2, but ... */ +#pragma omp requires atomic_default_mem_order(acquire) /* { dg-error "more than one 'atomic_default_mem_order' clause in a single compilation unit" } */ diff --git a/gcc/testsuite/c-c++-common/gomp/requires-5.c b/gcc/testsuite/c-c++-common/gomp/requires-5.c new file mode 100644 index 00000000000..53e0b75f1b7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/requires-5.c @@ -0,0 +1,23 @@ +/* { dg-additional-options "-fdump-tree-original" } */ + +#pragma omp requires atomic_default_mem_order(release) + +int +foo (int x, int y) +{ + int z; + + #pragma omp atomic write + x = y; + + #pragma omp atomic update + x += 1; + + #pragma omp atomic read acquire + z = x; + return z; +} + +/* { dg-final { scan-tree-dump "#pragma omp atomic release" "original" } } */ +/* { dg-final { scan-tree-dump "#pragma omp atomic release" "original" } } */ +/* { dg-final { scan-tree-dump "z = #pragma omp atomic read acquire" "original" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/requires-6.c b/gcc/testsuite/c-c++-common/gomp/requires-6.c new file mode 100644 index 00000000000..4470c8cae1a --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/requires-6.c @@ -0,0 +1,23 @@ +/* { dg-additional-options "-fdump-tree-original" } */ + +#pragma omp requires atomic_default_mem_order(acquire) + +int +bar (int a, int b) +{ + int c; + + #pragma omp atomic write release + a = b; + + #pragma omp atomic update + a += 1; + + #pragma omp atomic read + c = a; + return c; +} + +/* { dg-final { scan-tree-dump "#pragma omp atomic release" "original" } } */ +/* { dg-final { scan-tree-dump "#pragma omp atomic acquire" "original" } } */ +/* { dg-final { scan-tree-dump "c = #pragma omp atomic read acquire" "original" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/requires-7.c b/gcc/testsuite/c-c++-common/gomp/requires-7.c new file mode 100644 index 00000000000..4735ef2a6e0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/requires-7.c @@ -0,0 +1,11 @@ +#pragma omp requires atomic_default_mem_order(release) + +int +foo (int x) +{ + int z; + + #pragma omp atomic read /* { dg-error "'#pragma omp atomic read' incompatible with 'release' clause implicitly provided by a 'requires' directive" } */ + z = x; + return z; +} diff --git a/gcc/testsuite/c-c++-common/gomp/requires-8.c b/gcc/testsuite/c-c++-common/gomp/requires-8.c new file mode 100644 index 00000000000..4d56e7d33e9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/requires-8.c @@ -0,0 +1,14 @@ +#pragma omp requires atomic_default_mem_order(acquire) + +int +bar (int a, int b) +{ + int c; + + #pragma omp atomic write /* { dg-error "'#pragma omp atomic write' incompatible with 'acquire' clause implicitly provided by a 'requires' directive" } */ + a = b; + + #pragma omp atomic read + c = a; + return c; +} diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-10.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-10.f90 new file mode 100644 index 00000000000..e912e3e867f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-10.f90 @@ -0,0 +1,36 @@ +! { dg-additional-options "-fdump-tree-original" } + +function foo (x, y) result (z) + !$omp requires atomic_default_mem_order(release) + implicit none + real :: x, y, z + + !$omp atomic write + x = y + + !$omp atomic update + x = x + 1 + + !$omp atomic read acquire + z = x +end + +function bar (a, b) result (c) + !$omp requires atomic_default_mem_order(acquire) + implicit none + real :: a, b, c + + !$omp atomic write release + a = b + + !$omp atomic update + a = a + 1 + + !$omp atomic read + c = a +end + +! { dg-final { scan-tree-dump-times "#pragma omp atomic release" 3 "original" } } */ +! { dg-final { scan-tree-dump-times "#pragma omp atomic acquire" 1 "original" } } */ +! { dg-final { scan-tree-dump-times "z = #pragma omp atomic read acquire" 1 "original" } } */ +! { dg-final { scan-tree-dump-times "c = #pragma omp atomic read acquire" 1 "original" } } */ diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-11.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-11.f90 new file mode 100644 index 00000000000..c55009d5d26 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/requires-11.f90 @@ -0,0 +1,31 @@ +function foo (x, y) result (z) + !$omp requires atomic_default_mem_order(release) + implicit none + real :: x, y, z + + !$omp atomic write + x = y + + !$omp atomic update + x = x + 1 + + !$omp atomic read ! { dg-error "!.OMP ATOMIC READ at .1. incompatible with RELEASE clause implicitly provided by a REQUIRES directive" } + z = x +end + +function bar (a, b) result (c) + !$omp requires atomic_default_mem_order(acquire) + implicit none + real :: a, b, c + + !$omp atomic write ! { dg-error "!.OMP ATOMIC WRITE at .1. incompatible with ACQUIRES clause implicitly provided by a REQUIRES directive" } + a = b + + !$omp atomic update + a = a + 1 + + !$omp atomic read + c = a +end + + diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-2.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-2.f90 index 7b63d4a8b3b..5f11a7bfb2a 100644 --- a/gcc/testsuite/gfortran.dg/gomp/requires-2.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/requires-2.f90 @@ -8,7 +8,7 @@ !$omp requires atomic_default_mem_order (seq_cst) !$omp requires atomic_default_mem_order (seq_cst) !$omp requires atomic_default_mem_order (acq_rel) ! { dg-error "overrides a previous 'atomic_default_mem_order\\(seq_cst\\)'" } -!$omp requires atomic_default_mem_order (foo) ! { dg-error "Expected SEQ_CST, ACQ_REL or RELAXED for ATOMIC_DEFAULT_MEM_ORDER clause" } +!$omp requires atomic_default_mem_order (foo) ! { dg-error "Expected ACQ_REL, ACQUIRE, RELAXED, RELEASE or SEQ_CST for ATOMIC_DEFAULT_MEM_ORDER clause" } 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 index 4429aab2ee6..8c9d6ed3b21 100644 --- a/gcc/testsuite/gfortran.dg/gomp/requires-3.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/requires-3.f90 @@ -1,4 +1,5 @@ -!$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" } +!$omp requires atomic_default_mem_order(foobar) ! { dg-error "Expected ACQ_REL, ACQUIRE, RELAXED, RELEASE or SEQ_CST for ATOMIC_DEFAULT_MEM_ORDER clause" } + +!$omp requires atomic_default_mem_order(acquire) ! OK since OpenMP 5.2 +!$omp requires atomic_default_mem_order(release) ! { dg-error "!.OMP REQUIRES clause 'atomic_default_mem_order\\(release\\)' specified at .1. overrides a previous 'atomic_default_mem_order\\(acquire\\)' \\(which might be through using a module\\)" } end diff --git a/gcc/testsuite/gfortran.dg/gomp/requires-5.f90 b/gcc/testsuite/gfortran.dg/gomp/requires-5.f90 index ade2a3613c6..e719e929294 100644 --- a/gcc/testsuite/gfortran.dg/gomp/requires-5.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/requires-5.f90 @@ -8,7 +8,7 @@ subroutine foo !$omp requires unified_shared_memory !$omp requires atomic_default_mem_order(relaxed) !$omp requires atomic_default_mem_order(relaxed) -!$omp requires atomic_default_mem_order(seq_cst) ! { dg-error "overrides a previous 'atomic_default_mem_order\\(seq_cst\\)'" } +!$omp requires atomic_default_mem_order(seq_cst) ! { dg-error "overrides a previous 'atomic_default_mem_order\\(relaxed\\)'" } !$omp target !$omp end target end