aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/c-parser.cc32
-rw-r--r--gcc/cp/parser.cc32
-rw-r--r--gcc/fortran/gfortran.h22
-rw-r--r--gcc/fortran/module.cc19
-rw-r--r--gcc/fortran/openmp.cc53
-rw-r--r--gcc/fortran/parse.cc8
-rw-r--r--gcc/testsuite/c-c++-common/gomp/requires-3.c8
-rw-r--r--gcc/testsuite/c-c++-common/gomp/requires-5.c23
-rw-r--r--gcc/testsuite/c-c++-common/gomp/requires-6.c23
-rw-r--r--gcc/testsuite/c-c++-common/gomp/requires-7.c11
-rw-r--r--gcc/testsuite/c-c++-common/gomp/requires-8.c14
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/requires-10.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/requires-11.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/requires-2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/requires-3.f907
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/requires-5.f902
16 files changed, 291 insertions, 32 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index df9a079..5700ccc 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 "
+ "%<acquire%> clause implicitly provided by a "
+ "%<requires%> 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 "
+ "%<release%> clause implicitly provided by a "
+ "%<requires%> 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 %<seq_cst%>, %<relaxed%> or "
- "%<acq_rel%>");
+ "expected %<acq_rel%>, %<acquire%>, "
+ "%<relaxed%>, %<release%> or %<seq_cst%>");
switch (c_parser_peek_token (parser)->type)
{
case CPP_EOF:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index b987324..fe8845b 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -42504,6 +42504,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 "
+ "%<acquire%> clause implicitly provided by a "
+ "%<requires%> 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 "
+ "%<release%> clause implicitly provided by a "
+ "%<requires%> directive");
+ memory_order = OMP_MEMORY_ORDER_SEQ_CST;
+ }
+ else
+ memory_order = OMP_MEMORY_ORDER_RELEASE;
+ break;
case OMP_MEMORY_ORDER_ACQ_REL:
switch (code)
{
@@ -49194,15 +49216,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 %<seq_cst%>, %<relaxed%> or "
- "%<acq_rel%>");
+ "expected %<acq_rel%>, %<acquire%>, "
+ "%<relaxed%>, %<release%> or %<seq_cst%>");
switch (cp_lexer_peek_token (parser->lexer)->type)
{
case CPP_EOF:
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 28569d0..c86a025 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
@@ -2258,7 +2262,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 c07e9dc..3c07818 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),
@@ -2443,8 +2446,14 @@ mio_symbol_attribute (symbol_attribute *attr)
== 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 251da66..8c0e544 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 %<atomic_default_mem_order(%s)%> "
@@ -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 c0eb057..9b4c392 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -7274,10 +7274,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 bd2479b..2fd601a 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 0000000..53e0b75
--- /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 0000000..4470c8cae
--- /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 0000000..4735ef2
--- /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 0000000..4d56e7d
--- /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 0000000..e912e3e
--- /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 0000000..c55009d
--- /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 7b63d4a..5f11a7b 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 4429aab..8c9d6ed 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 ade2a36..e719e92 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