[clang] 9a3740c - [OPENMP50]Add restrictions for memory order clauses in atomic directive.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 11 07:17:08 PST 2020


Author: Alexey Bataev
Date: 2020-02-11T10:10:41-05:00
New Revision: 9a3740c33919287fd9aa4e0c6f761619e84c62a7

URL: https://github.com/llvm/llvm-project/commit/9a3740c33919287fd9aa4e0c6f761619e84c62a7
DIFF: https://github.com/llvm/llvm-project/commit/9a3740c33919287fd9aa4e0c6f761619e84c62a7.diff

LOG: [OPENMP50]Add restrictions for memory order clauses in atomic directive.

Added restrictions for atomic directive.
1. If atomic-clause is read then memory-order-clause must not be acq_rel or release.
2. If atomic-clause is write then memory-order-clause must not be
   acq_rel or acquire.
3. If atomic-clause is update or not present then memory-order-clause
   must not be acq_rel or acquire.

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaOpenMP.cpp
    clang/test/OpenMP/atomic_ast_print.cpp
    clang/test/OpenMP/atomic_messages.cpp
    clang/test/OpenMP/atomic_read_codegen.c
    clang/test/OpenMP/atomic_update_codegen.cpp
    clang/test/OpenMP/atomic_write_codegen.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 450075f2e927..9e4e89e61031 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9697,6 +9697,8 @@ def err_omp_atomic_several_clauses : Error<
   "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">;
 def err_omp_several_mem_order_clauses : Error<
   "directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', |}1'acq_rel', 'acquire' or 'release' clause">;
+def err_omp_atomic_incompatible_mem_order_clause : Error<
+  "directive '#pragma omp atomic%select{ %0|}1' cannot be used with '%2' clause">;
 def note_omp_previous_mem_order_clause : Note<
   "'%0' clause used here">;
 def err_omp_target_contains_not_only_teams : Error<

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 2e3c75fed370..313c9791bf87 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -8968,6 +8968,28 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
       }
     }
   }
+  // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
+  // If atomic-clause is read then memory-order-clause must not be acq_rel or
+  // release.
+  // If atomic-clause is write then memory-order-clause must not be acq_rel or
+  // acquire.
+  // If atomic-clause is update or not present then memory-order-clause must not
+  // be acq_rel or acquire.
+  if ((AtomicKind == OMPC_read &&
+       (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
+      ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
+        AtomicKind == OMPC_unknown) &&
+       (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
+    SourceLocation Loc = AtomicKindLoc;
+    if (AtomicKind == OMPC_unknown)
+      Loc = StartLoc;
+    Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
+        << getOpenMPClauseName(AtomicKind)
+        << (AtomicKind == OMPC_unknown ? 1 : 0)
+        << getOpenMPClauseName(MemOrderKind);
+    Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
+        << getOpenMPClauseName(MemOrderKind);
+  }
 
   Stmt *Body = CS->getCapturedStmt();
   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))

diff  --git a/clang/test/OpenMP/atomic_ast_print.cpp b/clang/test/OpenMP/atomic_ast_print.cpp
index 4dd64a75f2c9..f3f2883d2368 100644
--- a/clang/test/OpenMP/atomic_ast_print.cpp
+++ b/clang/test/OpenMP/atomic_ast_print.cpp
@@ -44,13 +44,13 @@ T foo(T argc) {
     a = b;
     b++;
   }
-#pragma omp atomic acq_rel
+#pragma omp atomic
   a++;
-#pragma omp atomic read acq_rel
+#pragma omp atomic read
   a = argc;
-#pragma omp atomic acq_rel write
+#pragma omp atomic write
   a = argc + argc;
-#pragma omp atomic update acq_rel
+#pragma omp atomic update
   a = a + argc;
 #pragma omp atomic acq_rel capture
   a = b++;
@@ -59,13 +59,13 @@ T foo(T argc) {
     a = b;
     b++;
   }
-#pragma omp atomic acquire
+#pragma omp atomic
   a++;
 #pragma omp atomic read acquire
   a = argc;
-#pragma omp atomic acquire write
+#pragma omp atomic write
   a = argc + argc;
-#pragma omp atomic update acquire
+#pragma omp atomic update
   a = a + argc;
 #pragma omp atomic acquire capture
   a = b++;
@@ -76,7 +76,7 @@ T foo(T argc) {
   }
 #pragma omp atomic release
   a++;
-#pragma omp atomic read release
+#pragma omp atomic read
   a = argc;
 #pragma omp atomic release write
   a = argc + argc;
@@ -123,13 +123,13 @@ T foo(T argc) {
 // CHECK-NEXT: a = b;
 // CHECK-NEXT: b++;
 // CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp atomic acq_rel
+// CHECK-NEXT: #pragma omp atomic
 // CHECK-NEXT: a++;
-// CHECK-NEXT: #pragma omp atomic read acq_rel
+// CHECK-NEXT: #pragma omp atomic read
 // CHECK-NEXT: a = argc;
-// CHECK-NEXT: #pragma omp atomic acq_rel write
+// CHECK-NEXT: #pragma omp atomic write
 // CHECK-NEXT: a = argc + argc;
-// CHECK-NEXT: #pragma omp atomic update acq_rel
+// CHECK-NEXT: #pragma omp atomic update
 // CHECK-NEXT: a = a + argc;
 // CHECK-NEXT: #pragma omp atomic acq_rel capture
 // CHECK-NEXT: a = b++;
@@ -138,13 +138,13 @@ T foo(T argc) {
 // CHECK-NEXT: a = b;
 // CHECK-NEXT: b++;
 // CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp atomic acquire
+// CHECK-NEXT: #pragma omp atomic
 // CHECK-NEXT: a++;
 // CHECK-NEXT: #pragma omp atomic read acquire
 // CHECK-NEXT: a = argc;
-// CHECK-NEXT: #pragma omp atomic acquire write
+// CHECK-NEXT: #pragma omp atomic write
 // CHECK-NEXT: a = argc + argc;
-// CHECK-NEXT: #pragma omp atomic update acquire
+// CHECK-NEXT: #pragma omp atomic update
 // CHECK-NEXT: a = a + argc;
 // CHECK-NEXT: #pragma omp atomic acquire capture
 // CHECK-NEXT: a = b++;
@@ -155,7 +155,7 @@ T foo(T argc) {
 // CHECK-NEXT: }
 // CHECK-NEXT: #pragma omp atomic release
 // CHECK-NEXT: a++;
-// CHECK-NEXT: #pragma omp atomic read release
+// CHECK-NEXT: #pragma omp atomic read
 // CHECK-NEXT: a = argc;
 // CHECK-NEXT: #pragma omp atomic release write
 // CHECK-NEXT: a = argc + argc;
@@ -199,13 +199,13 @@ T foo(T argc) {
 // CHECK-NEXT: a = b;
 // CHECK-NEXT: b++;
 // CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp atomic acq_rel
+// CHECK-NEXT: #pragma omp atomic
 // CHECK-NEXT: a++;
-// CHECK-NEXT: #pragma omp atomic read acq_rel
+// CHECK-NEXT: #pragma omp atomic read
 // CHECK-NEXT: a = argc;
-// CHECK-NEXT: #pragma omp atomic acq_rel write
+// CHECK-NEXT: #pragma omp atomic write
 // CHECK-NEXT: a = argc + argc;
-// CHECK-NEXT: #pragma omp atomic update acq_rel
+// CHECK-NEXT: #pragma omp atomic update
 // CHECK-NEXT: a = a + argc;
 // CHECK-NEXT: #pragma omp atomic acq_rel capture
 // CHECK-NEXT: a = b++;
@@ -214,13 +214,13 @@ T foo(T argc) {
 // CHECK-NEXT: a = b;
 // CHECK-NEXT: b++;
 // CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp atomic acquire
+// CHECK-NEXT: #pragma omp atomic
 // CHECK-NEXT: a++;
 // CHECK-NEXT: #pragma omp atomic read acquire
 // CHECK-NEXT: a = argc;
-// CHECK-NEXT: #pragma omp atomic acquire write
+// CHECK-NEXT: #pragma omp atomic write
 // CHECK-NEXT: a = argc + argc;
-// CHECK-NEXT: #pragma omp atomic update acquire
+// CHECK-NEXT: #pragma omp atomic update
 // CHECK-NEXT: a = a + argc;
 // CHECK-NEXT: #pragma omp atomic acquire capture
 // CHECK-NEXT: a = b++;
@@ -231,7 +231,7 @@ T foo(T argc) {
 // CHECK-NEXT: }
 // CHECK-NEXT: #pragma omp atomic release
 // CHECK-NEXT: a++;
-// CHECK-NEXT: #pragma omp atomic read release
+// CHECK-NEXT: #pragma omp atomic read
 // CHECK-NEXT: a = argc;
 // CHECK-NEXT: #pragma omp atomic release write
 // CHECK-NEXT: a = argc + argc;
@@ -279,13 +279,13 @@ int main(int argc, char **argv) {
     a = b;
     b++;
   }
-#pragma omp atomic acq_rel
+#pragma omp atomic
   a++;
-#pragma omp atomic read acq_rel
+#pragma omp atomic read
   a = argc;
-#pragma omp atomic acq_rel write
+#pragma omp atomic write
   a = argc + argc;
-#pragma omp atomic update acq_rel
+#pragma omp atomic update
   a = a + argc;
 #pragma omp atomic acq_rel capture
   a = b++;
@@ -294,13 +294,13 @@ int main(int argc, char **argv) {
     a = b;
     b++;
   }
-#pragma omp atomic acquire
+#pragma omp atomic
   a++;
 #pragma omp atomic read acquire
   a = argc;
-#pragma omp atomic acquire write
+#pragma omp atomic write
   a = argc + argc;
-#pragma omp atomic update acquire
+#pragma omp atomic update
   a = a + argc;
 #pragma omp atomic acquire capture
   a = b++;
@@ -311,7 +311,7 @@ int main(int argc, char **argv) {
   }
 #pragma omp atomic release
   a++;
-#pragma omp atomic read release
+#pragma omp atomic read
   a = argc;
 #pragma omp atomic release write
   a = argc + argc;
@@ -354,13 +354,13 @@ int main(int argc, char **argv) {
   // CHECK-NEXT: a = b;
   // CHECK-NEXT: b++;
   // CHECK-NEXT: }
-  // CHECK-NEXT: #pragma omp atomic acq_rel
+  // CHECK-NEXT: #pragma omp atomic
   // CHECK-NEXT: a++;
-  // CHECK-NEXT: #pragma omp atomic read acq_rel
+  // CHECK-NEXT: #pragma omp atomic read
   // CHECK-NEXT: a = argc;
-  // CHECK-NEXT: #pragma omp atomic acq_rel write
+  // CHECK-NEXT: #pragma omp atomic write
   // CHECK-NEXT: a = argc + argc;
-  // CHECK-NEXT: #pragma omp atomic update acq_rel
+  // CHECK-NEXT: #pragma omp atomic update
   // CHECK-NEXT: a = a + argc;
   // CHECK-NEXT: #pragma omp atomic acq_rel capture
   // CHECK-NEXT: a = b++;
@@ -369,13 +369,13 @@ int main(int argc, char **argv) {
   // CHECK-NEXT: a = b;
   // CHECK-NEXT: b++;
   // CHECK-NEXT: }
-  // CHECK-NEXT: #pragma omp atomic acquire
+  // CHECK-NEXT: #pragma omp atomic
   // CHECK-NEXT: a++;
   // CHECK-NEXT: #pragma omp atomic read acquire
   // CHECK-NEXT: a = argc;
-  // CHECK-NEXT: #pragma omp atomic acquire write
+  // CHECK-NEXT: #pragma omp atomic write
   // CHECK-NEXT: a = argc + argc;
-  // CHECK-NEXT: #pragma omp atomic update acquire
+  // CHECK-NEXT: #pragma omp atomic update
   // CHECK-NEXT: a = a + argc;
   // CHECK-NEXT: #pragma omp atomic acquire capture
   // CHECK-NEXT: a = b++;
@@ -386,7 +386,7 @@ int main(int argc, char **argv) {
   // CHECK-NEXT: }
   // CHECK-NEXT: #pragma omp atomic release
   // CHECK-NEXT: a++;
-  // CHECK-NEXT: #pragma omp atomic read release
+  // CHECK-NEXT: #pragma omp atomic read
   // CHECK-NEXT: a = argc;
   // CHECK-NEXT: #pragma omp atomic release write
   // CHECK-NEXT: a = argc + argc;

diff  --git a/clang/test/OpenMP/atomic_messages.cpp b/clang/test/OpenMP/atomic_messages.cpp
index d595689e4d15..af5fc90b35a3 100644
--- a/clang/test/OpenMP/atomic_messages.cpp
+++ b/clang/test/OpenMP/atomic_messages.cpp
@@ -728,16 +728,16 @@ int seq_cst() {
 template <class T>
 T acq_rel() {
   T a = 0, b = 0;
-// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic' cannot be used with 'acq_rel' clause}} omp50-note at +1 {{'acq_rel' clause used here}}
 #pragma omp atomic acq_rel
   // expected-error at +2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
   ;
-// omp50-error at +1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 2 {{'acq_rel' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
-#pragma omp atomic acq_rel seq_cst
-  a += b;
+// omp50-error at +1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 2 {{'acq_rel' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error at +1 2 {{directive '#pragma omp atomic read' cannot be used with 'acq_rel' clause}} omp50-note at +1 2 {{'acq_rel' clause used here}}
+#pragma omp atomic read acq_rel seq_cst
+  a = b;
 
-// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic update' cannot be used with 'acq_rel' clause}} omp50-note at +1 {{'acq_rel' clause used here}}
 #pragma omp atomic update acq_rel
   // expected-error at +2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
@@ -749,16 +749,16 @@ T acq_rel() {
 int acq_rel() {
   int a = 0, b = 0;
 // Test for atomic acq_rel
-// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
-#pragma omp atomic acq_rel
-  // expected-error at +2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic write' cannot be used with 'acq_rel' clause}} omp50-note at +1 {{'acq_rel' clause used here}}
+#pragma omp atomic acq_rel write
+  // expected-error at +2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
   ;
 // omp50-error at +1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 {{'seq_cst' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
 #pragma omp atomic seq_cst acq_rel
   a += b;
 
-// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic update' cannot be used with 'acq_rel' clause}} omp50-note at +1 {{'acq_rel' clause used here}}
 #pragma omp atomic update acq_rel
   // expected-error at +2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
@@ -770,16 +770,16 @@ int acq_rel() {
 template <class T>
 T acquire() {
   T a = 0, b = 0;
-// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic' cannot be used with 'acquire' clause}} omp50-note at +1 {{'acquire' clause used here}}
 #pragma omp atomic acquire
   // expected-error at +2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
   ;
-// omp50-error at +1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 2 {{'acquire' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}}
+// omp50-error at +1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 2 {{'acquire' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error at +1 2 {{directive '#pragma omp atomic' cannot be used with 'acquire' clause}} omp50-note at +1 2 {{'acquire' clause used here}}
 #pragma omp atomic acquire seq_cst
   a += b;
 
-// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic update' cannot be used with 'acquire' clause}} omp50-note at +1 {{'acquire' clause used here}}
 #pragma omp atomic update acquire
   // expected-error at +2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
@@ -791,16 +791,16 @@ T acquire() {
 int acquire() {
   int a = 0, b = 0;
 // Test for atomic acquire
-// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}}
-#pragma omp atomic acquire
-  // expected-error at +2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic write' cannot be used with 'acquire' clause}} omp50-note at +1 {{'acquire' clause used here}}
+#pragma omp atomic write acquire
+  // expected-error at +2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
   ;
 // omp50-error at +1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 {{'seq_cst' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}}
 #pragma omp atomic seq_cst acquire
   a += b;
 
-// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}}
+// omp45-error at +1 {{unexpected OpenMP clause 'acquire' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic update' cannot be used with 'acquire' clause}} omp50-note at +1 {{'acquire' clause used here}}
 #pragma omp atomic update acquire
   // expected-error at +2 {{the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
@@ -833,9 +833,9 @@ T release() {
 int release() {
   int a = 0, b = 0;
 // Test for atomic release
-// omp45-error at +1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
-#pragma omp atomic release
-  // expected-error at +2 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
+// omp45-error at +1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}} omp50-error at +1 {{directive '#pragma omp atomic read' cannot be used with 'release' clause}} omp50-note at +1 {{'release' clause used here}}
+#pragma omp atomic read release
+  // expected-error at +2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
   // expected-note at +1 {{expected an expression statement}}
   ;
 // omp50-error at +1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 {{'seq_cst' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}

diff  --git a/clang/test/OpenMP/atomic_read_codegen.c b/clang/test/OpenMP/atomic_read_codegen.c
index 814975e38ea2..8d49115bc603 100644
--- a/clang/test/OpenMP/atomic_read_codegen.c
+++ b/clang/test/OpenMP/atomic_read_codegen.c
@@ -312,7 +312,7 @@ int main() {
 // CHECK: [[SHL:%.+]] = shl i64 [[LD]], 40
 // CHECK: [[ASHR:%.+]] = ashr i64 [[SHL]], 57
 // CHECK: store x86_fp80
-#pragma omp atomic read release
+#pragma omp atomic read
   ldv = bfx4.b;
 // CHECK: [[LD:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @bfx4_packed, i32 0, i32 0, i64 2) acquire
 // CHECK: store i8 [[LD]], i8* [[LDTEMP:%.+]]
@@ -323,14 +323,13 @@ int main() {
 // CHECK: store x86_fp80
 #pragma omp atomic read acquire
   ldv = bfx4_packed.b;
-// CHECK: [[LD:%.+]] = load atomic i64, i64* bitcast (<2 x float>* @{{.+}} to i64*) acquire
+// CHECK: [[LD:%.+]] = load atomic i64, i64* bitcast (<2 x float>* @{{.+}} to i64*) monotonic
 // CHECK: [[BITCAST:%.+]] = bitcast <2 x float>* [[LDTEMP:%.+]] to i64*
 // CHECK: store i64 [[LD]], i64* [[BITCAST]]
 // CHECK: [[LD:%.+]] = load <2 x float>, <2 x float>* [[LDTEMP]]
 // CHECK: extractelement <2 x float> [[LD]]
-// CHECK: call{{.*}} @__kmpc_flush(
 // CHECK: store i64
-#pragma omp atomic read acq_rel
+#pragma omp atomic read
   ulv = float2x.x;
 // CHECK: call{{.*}} i{{[0-9]+}} @llvm.read_register
 // CHECK: call{{.*}} @__kmpc_flush(

diff  --git a/clang/test/OpenMP/atomic_update_codegen.cpp b/clang/test/OpenMP/atomic_update_codegen.cpp
index fb900753898c..7913dc1ce69f 100644
--- a/clang/test/OpenMP/atomic_update_codegen.cpp
+++ b/clang/test/OpenMP/atomic_update_codegen.cpp
@@ -812,7 +812,7 @@ int main() {
 #pragma omp atomic update
   bfx4_packed.a -= ldv;
 // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
-// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) acquire
+// CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic
 // CHECK: br label %[[CONT:.+]]
 // CHECK: [[CONT]]
 // CHECK: [[OLD_BF_VALUE:%.+]] = phi i64 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
@@ -831,15 +831,15 @@ int main() {
 // CHECK: [[VAL:%.+]] = or i64 [[BF_CLEAR]], [[BF_VALUE]]
 // CHECK: store i64 [[VAL]], i64* [[TEMP1]]
 // CHECK: [[NEW_BF_VALUE:%.+]] = load i64, i64* [[TEMP1]]
-// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] acquire acquire
+// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (%struct.BitFields4* @{{.+}} to i64*), i64 [[OLD_BF_VALUE]], i64 [[NEW_BF_VALUE]] monotonic monotonic
 // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i64, i1 } [[RES]], 0
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-#pragma omp atomic acquire
+#pragma omp atomic
   bfx4.b /= ldv;
 // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
-// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) acquire
+// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic
 // CHECK: br label %[[CONT:.+]]
 // CHECK: [[CONT]]
 // CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
@@ -861,17 +861,16 @@ int main() {
 // CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
 // CHECK: store i8 %{{.+}}, i8* [[BITCAST1]]
 // CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[BITCAST1]]
-// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] acq_rel acquire
+// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic
 // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-// CHECK: call{{.*}} @__kmpc_flush(
-#pragma omp atomic update acq_rel
+#pragma omp atomic update
   bfx4_packed.b += ldv;
 // CHECK: load i64, i64*
 // CHECK: [[EXPR:%.+]] = uitofp i64 %{{.+}} to float
-// CHECK: [[I64VAL:%.+]] = load atomic i64, i64* bitcast (<2 x float>* [[DEST:@.+]] to i64*) acquire
+// CHECK: [[I64VAL:%.+]] = load atomic i64, i64* bitcast (<2 x float>* [[DEST:@.+]] to i64*) monotonic
 // CHECK: br label %[[CONT:.+]]
 // CHECK: [[CONT]]
 // CHECK: [[OLD_I64:%.+]] = phi i64 [ [[I64VAL]], %{{.+}} ], [ [[FAILED_I64_OLD_VAL:%.+]], %[[CONT]] ]
@@ -886,13 +885,12 @@ int main() {
 // CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <2 x float> [[VEC_VAL]], float [[VEC_ITEM_VAL]], i64 0
 // CHECK: store <2 x float> [[NEW_VEC_VAL]], <2 x float>* [[TEMP]]
 // CHECK: [[NEW_I64:%.+]] = load i64, i64* [[BITCAST]]
-// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (<2 x float>* [[DEST]] to i64*), i64 [[OLD_I64]], i64 [[NEW_I64]] acq_rel acquire
+// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (<2 x float>* [[DEST]] to i64*), i64 [[OLD_I64]], i64 [[NEW_I64]] monotonic monotonic
 // CHECK: [[FAILED_I64_OLD_VAL:%.+]] = extractvalue { i64, i1 } [[RES]], 0
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-// CHECK: call{{.*}} @__kmpc_flush(
-#pragma omp atomic acq_rel
+#pragma omp atomic
   float2x.x = ulv - float2x.x;
 // CHECK: [[EXPR:%.+]] = load double, double* @{{.+}},
 // CHECK: [[OLD_VAL:%.+]] = call i32 @llvm.read_register.i32([[REG:metadata ![0-9]+]])

diff  --git a/clang/test/OpenMP/atomic_write_codegen.c b/clang/test/OpenMP/atomic_write_codegen.c
index f8a74e8c6edd..053f46d55246 100644
--- a/clang/test/OpenMP/atomic_write_codegen.c
+++ b/clang/test/OpenMP/atomic_write_codegen.c
@@ -88,7 +88,7 @@ int main() {
  __imag(civ) = 1;
 // CHECK: load i8, i8*
 // CHECK: store atomic i8{{.*}}monotonic
-#pragma omp atomic write acquire
+#pragma omp atomic write
   bx = bv;
 // CHECK: load i8, i8*
 // CHECK: store atomic i8{{.*}}release
@@ -470,7 +470,7 @@ int main() {
   bfx4.b = ldv;
 // CHECK: load x86_fp80, x86_fp80* @{{.+}}
 // CHECK: [[NEW_VAL:%.+]] = fptosi x86_fp80 %{{.+}} to i64
-// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) acquire
+// CHECK: [[PREV_VALUE:%.+]] = load atomic i8, i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2) monotonic
 // CHECK: br label %[[CONT:.+]]
 // CHECK: [[CONT]]
 // CHECK: [[OLD_BF_VALUE:%.+]] = phi i8 [ [[PREV_VALUE]], %[[EXIT]] ], [ [[FAILED_OLD_VAL:%.+]], %[[CONT]] ]
@@ -481,16 +481,16 @@ int main() {
 // CHECK: or i8 [[BF_CLEAR]], [[BF_VALUE]]
 // CHECK: store i8 %{{.+}}, i8* [[LDTEMP:%.+]]
 // CHECK: [[NEW_BF_VALUE:%.+]] = load i8, i8* [[LDTEMP]]
-// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] acquire acquire
+// CHECK: [[RES:%.+]] = cmpxchg i8* getelementptr inbounds (%struct.BitFields4_packed, %struct.BitFields4_packed* @{{.+}}, i32 0, i32 0, i64 2), i8 [[OLD_BF_VALUE]], i8 [[NEW_BF_VALUE]] monotonic monotonic
 // CHECK: [[FAILED_OLD_VAL]] = extractvalue { i8, i1 } [[RES]], 0
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-#pragma omp atomic write acquire
+#pragma omp atomic write
   bfx4_packed.b = ldv;
 // CHECK: load i64, i64*
 // CHECK: [[VEC_ITEM_VAL:%.+]] = uitofp i64 %{{.+}} to float
-// CHECK: [[I64VAL:%.+]] = load atomic i64, i64* bitcast (<2 x float>* [[DEST:@.+]] to i64*) acquire
+// CHECK: [[I64VAL:%.+]] = load atomic i64, i64* bitcast (<2 x float>* [[DEST:@.+]] to i64*) monotonic
 // CHECK: br label %[[CONT:.+]]
 // CHECK: [[CONT]]
 // CHECK: [[OLD_I64:%.+]] = phi i64 [ [[I64VAL]], %{{.+}} ], [ [[FAILED_I64_OLD_VAL:%.+]], %[[CONT]] ]
@@ -500,13 +500,12 @@ int main() {
 // CHECK: [[NEW_VEC_VAL:%.+]] = insertelement <2 x float> [[VEC_VAL]], float [[VEC_ITEM_VAL]], i64 0
 // CHECK: store <2 x float> [[NEW_VEC_VAL]], <2 x float>* [[LDTEMP]]
 // CHECK: [[NEW_I64:%.+]] = load i64, i64* [[BITCAST]]
-// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (<2 x float>* [[DEST]] to i64*), i64 [[OLD_I64]], i64 [[NEW_I64]] acq_rel acquire
+// CHECK: [[RES:%.+]] = cmpxchg i64* bitcast (<2 x float>* [[DEST]] to i64*), i64 [[OLD_I64]], i64 [[NEW_I64]] monotonic monotonic
 // CHECK: [[FAILED_I64_OLD_VAL:%.+]] = extractvalue { i64, i1 } [[RES]], 0
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-// CHECK: call{{.*}} @__kmpc_flush(
-#pragma omp atomic write acq_rel
+#pragma omp atomic write
   float2x.x = ulv;
 // CHECK: call i32 @llvm.read_register.i32(
 // CHECK: sitofp i32 %{{.+}} to double


        


More information about the cfe-commits mailing list