[clang] 9a8defc - [OPENMP50]Add support for relaxed clause in atomic directive.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 11 09:02:59 PST 2020


Author: Alexey Bataev
Date: 2020-02-11T11:54:46-05:00
New Revision: 9a8defcc34853e2cdc7d97f12df98c95930556ad

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

LOG: [OPENMP50]Add support for relaxed clause in atomic directive.

Added full support for relaxed clause.

Added: 
    

Modified: 
    clang/include/clang/AST/OpenMPClause.h
    clang/include/clang/AST/RecursiveASTVisitor.h
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Basic/OpenMPKinds.def
    clang/include/clang/Sema/Sema.h
    clang/lib/AST/OpenMPClause.cpp
    clang/lib/AST/StmtProfile.cpp
    clang/lib/Basic/OpenMPKinds.cpp
    clang/lib/CodeGen/CGStmtOpenMP.cpp
    clang/lib/Parse/ParseOpenMP.cpp
    clang/lib/Sema/SemaOpenMP.cpp
    clang/lib/Sema/TreeTransform.h
    clang/lib/Serialization/ASTReader.cpp
    clang/lib/Serialization/ASTWriter.cpp
    clang/test/OpenMP/atomic_ast_print.cpp
    clang/test/OpenMP/atomic_capture_codegen.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
    clang/test/OpenMP/flush_messages.cpp
    clang/tools/libclang/CIndex.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 19a84bd00a36..1e6c5f928eb9 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1995,6 +1995,46 @@ class OMPReleaseClause final : public OMPClause {
   }
 };
 
+/// This represents 'relaxed' clause in the '#pragma omp atomic'
+/// directives.
+///
+/// \code
+/// #pragma omp atomic relaxed
+/// \endcode
+/// In this example directive '#pragma omp atomic' has 'relaxed' clause.
+class OMPRelaxedClause final : public OMPClause {
+public:
+  /// Build 'relaxed' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_relaxed, StartLoc, EndLoc) {}
+
+  /// Build an empty clause.
+  OMPRelaxedClause()
+      : OMPClause(OMPC_relaxed, SourceLocation(), SourceLocation()) {}
+
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_relaxed;
+  }
+};
+
 /// This represents clause 'private' in the '#pragma omp ...' directives.
 ///
 /// \code

diff  --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 4ef9528dcf5b..bcbac210c00f 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3136,6 +3136,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) {
   return true;
 }
 
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPRelaxedClause(OMPRelaxedClause *) {
+  return true;
+}
+
 template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
   return true;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9e4e89e61031..e5714a744692 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9696,7 +9696,7 @@ def note_omp_atomic_capture: Note<
 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">;
+  "directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', 'relaxed', |}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<

diff  --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 19fcf7cfac58..13b3438fec2c 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -260,6 +260,7 @@ OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
 OPENMP_CLAUSE(acq_rel, OMPAcqRelClause)
 OPENMP_CLAUSE(acquire, OMPAcquireClause)
 OPENMP_CLAUSE(release, OMPReleaseClause)
+OPENMP_CLAUSE(relaxed, OMPRelaxedClause)
 OPENMP_CLAUSE(depend, OMPDependClause)
 OPENMP_CLAUSE(device, OMPDeviceClause)
 OPENMP_CLAUSE(threads, OMPThreadsClause)
@@ -495,6 +496,7 @@ OPENMP_ATOMIC_CLAUSE(seq_cst)
 OPENMP_ATOMIC_CLAUSE(acq_rel)
 OPENMP_ATOMIC_CLAUSE(acquire)
 OPENMP_ATOMIC_CLAUSE(release)
+OPENMP_ATOMIC_CLAUSE(relaxed)
 
 // Clauses allowed for OpenMP directive 'target'.
 OPENMP_TARGET_CLAUSE(if)

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 24cfceda45dc..a93addc5bee9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -10337,6 +10337,9 @@ class Sema final {
   /// Called on well-formed 'release' clause.
   OMPClause *ActOnOpenMPReleaseClause(SourceLocation StartLoc,
                                       SourceLocation EndLoc);
+  /// Called on well-formed 'relaxed' clause.
+  OMPClause *ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
+                                      SourceLocation EndLoc);
   /// Called on well-formed 'threads' clause.
   OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
                                       SourceLocation EndLoc);

diff  --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 2947665981af..6eac98250c8f 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -119,6 +119,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_depend:
   case OMPC_threads:
   case OMPC_simd:
@@ -196,6 +197,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_depend:
   case OMPC_device:
   case OMPC_threads:
@@ -1352,6 +1354,10 @@ void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
   OS << "release";
 }
 
+void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
+  OS << "relaxed";
+}
+
 void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
   OS << "threads";
 }

diff  --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index b303851a75c6..14ddc13ce561 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -524,6 +524,8 @@ void OMPClauseProfiler::VisitOMPAcquireClause(const OMPAcquireClause *) {}
 
 void OMPClauseProfiler::VisitOMPReleaseClause(const OMPReleaseClause *) {}
 
+void OMPClauseProfiler::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
+
 void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
 
 void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}

diff  --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 124723552af4..f13364e5378b 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -217,6 +217,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_device:
   case OMPC_threads:
   case OMPC_simd:
@@ -432,6 +433,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_device:
   case OMPC_threads:
   case OMPC_simd:
@@ -598,7 +600,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
     break;
   case OMPD_atomic:
     if (OpenMPVersion < 50 && (CKind == OMPC_acq_rel || CKind == OMPC_acquire ||
-                               CKind == OMPC_release))
+                               CKind == OMPC_release || CKind == OMPC_relaxed))
       return false;
     switch (CKind) {
 #define OPENMP_ATOMIC_CLAUSE(Name)                                             \

diff  --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index bc71c27fd95f..16914648a34d 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -4494,6 +4494,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_shared:
   case OMPC_linear:
   case OMPC_aligned:
@@ -4549,14 +4550,17 @@ void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
     AO = llvm::AtomicOrdering::Acquire;
   else if (S.getSingleClause<OMPReleaseClause>())
     AO = llvm::AtomicOrdering::Release;
+  else if (S.getSingleClause<OMPRelaxedClause>())
+    AO = llvm::AtomicOrdering::Monotonic;
   OpenMPClauseKind Kind = OMPC_unknown;
   for (const OMPClause *C : S.clauses()) {
-    // Find first clause (skip seq_cst|acq_rel|aqcuire|release clause, if it is
-    // first).
+    // Find first clause (skip seq_cst|acq_rel|aqcuire|release|relaxed clause,
+    // if it is first).
     if (C->getClauseKind() != OMPC_seq_cst &&
         C->getClauseKind() != OMPC_acq_rel &&
         C->getClauseKind() != OMPC_acquire &&
-        C->getClauseKind() != OMPC_release) {
+        C->getClauseKind() != OMPC_release &&
+        C->getClauseKind() != OMPC_relaxed) {
       Kind = C->getClauseKind();
       break;
     }

diff  --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 1a7916e5adb8..c893ffc13f51 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -2090,7 +2090,7 @@ bool Parser::ParseOpenMPSimpleVarList(
 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
 ///       in_reduction-clause | allocator-clause | allocate-clause |
-///       acq_rel-clause | acquire-clause | release-clause
+///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause
 ///
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                      OpenMPClauseKind CKind, bool FirstClause) {
@@ -2202,6 +2202,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_threads:
   case OMPC_simd:
   case OMPC_nogroup:

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 313c9791bf87..2a13f72f6936 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4990,6 +4990,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
       case OMPC_acq_rel:
       case OMPC_acquire:
       case OMPC_release:
+      case OMPC_relaxed:
       case OMPC_depend:
       case OMPC_threads:
       case OMPC_simd:
@@ -8955,7 +8956,8 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
     if (C->getClauseKind() == OMPC_seq_cst ||
         C->getClauseKind() == OMPC_acq_rel ||
         C->getClauseKind() == OMPC_acquire ||
-        C->getClauseKind() == OMPC_release) {
+        C->getClauseKind() == OMPC_release ||
+        C->getClauseKind() == OMPC_relaxed) {
       if (MemOrderKind != OMPC_unknown) {
         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
             << getOpenMPDirectiveName(OMPD_atomic) << 0
@@ -10918,6 +10920,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_depend:
   case OMPC_threads:
   case OMPC_simd:
@@ -11633,6 +11636,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_depend:
   case OMPC_threads:
   case OMPC_simd:
@@ -12058,6 +12062,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_depend:
   case OMPC_device:
   case OMPC_threads:
@@ -12261,6 +12266,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_depend:
   case OMPC_device:
   case OMPC_threads:
@@ -12443,6 +12449,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
   case OMPC_release:
     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
     break;
+  case OMPC_relaxed:
+    Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
+    break;
   case OMPC_threads:
     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
     break;
@@ -12571,6 +12580,11 @@ OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
 }
 
+OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
+                                          SourceLocation EndLoc) {
+  return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
+}
+
 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
                                           SourceLocation EndLoc) {
   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
@@ -12730,6 +12744,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
   case OMPC_acq_rel:
   case OMPC_acquire:
   case OMPC_release:
+  case OMPC_relaxed:
   case OMPC_device:
   case OMPC_threads:
   case OMPC_simd:

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index dffaf8938627..3f3915b8c44b 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -8825,6 +8825,13 @@ TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
   return C;
 }
 
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
 template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {

diff  --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index c9553de8143e..a1161d264838 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11675,6 +11675,9 @@ OMPClause *OMPClauseReader::readClause() {
   case OMPC_release:
     C = new (Context) OMPReleaseClause();
     break;
+  case OMPC_relaxed:
+    C = new (Context) OMPRelaxedClause();
+    break;
   case OMPC_threads:
     C = new (Context) OMPThreadsClause();
     break;
@@ -11943,6 +11946,8 @@ void OMPClauseReader::VisitOMPAcquireClause(OMPAcquireClause *) {}
 
 void OMPClauseReader::VisitOMPReleaseClause(OMPReleaseClause *) {}
 
+void OMPClauseReader::VisitOMPRelaxedClause(OMPRelaxedClause *) {}
+
 void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {}
 
 void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}

diff  --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index eb79ba20ddf7..f935a69769bf 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6153,6 +6153,8 @@ void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {}
 
 void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {}
 
+void OMPClauseWriter::VisitOMPRelaxedClause(OMPRelaxedClause *) {}
+
 void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
 
 void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}

diff  --git a/clang/test/OpenMP/atomic_ast_print.cpp b/clang/test/OpenMP/atomic_ast_print.cpp
index f3f2883d2368..5d8e92c14765 100644
--- a/clang/test/OpenMP/atomic_ast_print.cpp
+++ b/clang/test/OpenMP/atomic_ast_print.cpp
@@ -89,6 +89,21 @@ T foo(T argc) {
     a = b;
     b++;
   }
+#pragma omp atomic relaxed
+  a++;
+#pragma omp atomic read
+  a = argc;
+#pragma omp atomic relaxed write
+  a = argc + argc;
+#pragma omp atomic update relaxed
+  a = a + argc;
+#pragma omp atomic relaxed capture
+  a = b++;
+#pragma omp atomic capture relaxed
+  {
+    a = b;
+    b++;
+  }
   return T();
 }
 
@@ -168,6 +183,21 @@ T foo(T argc) {
 // CHECK-NEXT: a = b;
 // CHECK-NEXT: b++;
 // CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp atomic relaxed
+// CHECK-NEXT: a++;
+// CHECK-NEXT: #pragma omp atomic read
+// CHECK-NEXT: a = argc;
+// CHECK-NEXT: #pragma omp atomic relaxed write
+// CHECK-NEXT: a = argc + argc;
+// CHECK-NEXT: #pragma omp atomic update relaxed
+// CHECK-NEXT: a = a + argc;
+// CHECK-NEXT: #pragma omp atomic relaxed capture
+// CHECK-NEXT: a = b++;
+// CHECK-NEXT: #pragma omp atomic capture relaxed
+// CHECK-NEXT: {
+// CHECK-NEXT: a = b;
+// CHECK-NEXT: b++;
+// CHECK-NEXT: }
 // CHECK: int a = int();
 // CHECK-NEXT: #pragma omp atomic
 // CHECK-NEXT: a++;
@@ -244,6 +274,21 @@ T foo(T argc) {
 // CHECK-NEXT: a = b;
 // CHECK-NEXT: b++;
 // CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp atomic relaxed
+// CHECK-NEXT: a++;
+// CHECK-NEXT: #pragma omp atomic read
+// CHECK-NEXT: a = argc;
+// CHECK-NEXT: #pragma omp atomic relaxed write
+// CHECK-NEXT: a = argc + argc;
+// CHECK-NEXT: #pragma omp atomic update relaxed
+// CHECK-NEXT: a = a + argc;
+// CHECK-NEXT: #pragma omp atomic relaxed capture
+// CHECK-NEXT: a = b++;
+// CHECK-NEXT: #pragma omp atomic capture relaxed
+// CHECK-NEXT: {
+// CHECK-NEXT: a = b;
+// CHECK-NEXT: b++;
+// CHECK-NEXT: }
 
 int main(int argc, char **argv) {
   int b = 0;
@@ -324,6 +369,21 @@ int main(int argc, char **argv) {
     a = b;
     b++;
   }
+#pragma omp atomic relaxed
+  a++;
+#pragma omp atomic read
+  a = argc;
+#pragma omp atomic relaxed write
+  a = argc + argc;
+#pragma omp atomic update relaxed
+  a = a + argc;
+#pragma omp atomic relaxed capture
+  a = b++;
+#pragma omp atomic capture relaxed
+  {
+    a = b;
+    b++;
+  }
   // CHECK-NEXT: #pragma omp atomic
   // CHECK-NEXT: a++;
   // CHECK-NEXT: #pragma omp atomic read
@@ -399,6 +459,21 @@ int main(int argc, char **argv) {
   // CHECK-NEXT: a = b;
   // CHECK-NEXT: b++;
   // CHECK-NEXT: }
+  // CHECK-NEXT: #pragma omp atomic relaxed
+  // CHECK-NEXT: a++;
+  // CHECK-NEXT: #pragma omp atomic read
+  // CHECK-NEXT: a = argc;
+  // CHECK-NEXT: #pragma omp atomic relaxed write
+  // CHECK-NEXT: a = argc + argc;
+  // CHECK-NEXT: #pragma omp atomic update relaxed
+  // CHECK-NEXT: a = a + argc;
+  // CHECK-NEXT: #pragma omp atomic relaxed capture
+  // CHECK-NEXT: a = b++;
+  // CHECK-NEXT: #pragma omp atomic capture relaxed
+  // CHECK-NEXT: {
+  // CHECK-NEXT: a = b;
+  // CHECK-NEXT: b++;
+  // CHECK-NEXT: }
   return foo(a);
 }
 

diff  --git a/clang/test/OpenMP/atomic_capture_codegen.cpp b/clang/test/OpenMP/atomic_capture_codegen.cpp
index 3164c4f419f5..d7b8748bbc24 100644
--- a/clang/test/OpenMP/atomic_capture_codegen.cpp
+++ b/clang/test/OpenMP/atomic_capture_codegen.cpp
@@ -843,7 +843,7 @@ int main() {
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
 // CHECK: store i32 [[NEW_VAL]], i32* @{{.+}},
-#pragma omp atomic capture
+#pragma omp atomic relaxed capture
   iv = bfx4.a = bfx4.a * 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) monotonic
@@ -874,7 +874,7 @@ int main() {
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
 // CHECK: store i32 [[CAST]], i32* @{{.+}},
-#pragma omp atomic capture
+#pragma omp atomic capture relaxed
   {iv = bfx4_packed.a; bfx4_packed.a -= ldv;}
 // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
 // CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic

diff  --git a/clang/test/OpenMP/atomic_messages.cpp b/clang/test/OpenMP/atomic_messages.cpp
index af5fc90b35a3..c44405178c84 100644
--- a/clang/test/OpenMP/atomic_messages.cpp
+++ b/clang/test/OpenMP/atomic_messages.cpp
@@ -733,7 +733,7 @@ T 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'}} 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}}
+// omp50-error at +1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', '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;
 
@@ -754,7 +754,7 @@ int acq_rel() {
   // 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'}}
+// omp50-error at +1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', '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;
 
@@ -775,7 +775,7 @@ T 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 be used with 'acquire' clause}} omp50-note at +1 2 {{'acquire' clause used here}}
+// omp50-error at +1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', '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;
 
@@ -796,7 +796,7 @@ int 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'}}
+// omp50-error at +1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', '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;
 
@@ -817,7 +817,7 @@ T 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}}
   // 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 {{'release' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
+// omp50-error at +1 2 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 2 {{'release' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'release' in directive '#pragma omp atomic'}}
 #pragma omp atomic release seq_cst
   a += b;
 
@@ -838,7 +838,7 @@ int 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'}}
+// omp50-error at +1 {{directive '#pragma omp atomic' cannot contain more than one 'seq_cst', 'relaxed', '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'}}
 #pragma omp atomic seq_cst release
   a += b;
 
@@ -851,6 +851,48 @@ int release() {
  return release<int>(); // omp50-note {{in instantiation of function template specialization 'release<int>' requested here}}
 }
 
+template <class T>
+T relaxed() {
+  T a = 0, b = 0;
+// omp45-error at +1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
+#pragma omp atomic relaxed
+  // 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', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 2 {{'relaxed' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
+#pragma omp atomic relaxed seq_cst
+  a += b;
+
+// omp45-error at +1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
+#pragma omp atomic update relaxed
+  // 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}}
+  ;
+
+  return T();
+}
+
+int relaxed() {
+  int a = 0, b = 0;
+// Test for atomic relaxed
+// omp45-error at +1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
+#pragma omp atomic read relaxed
+  // 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', 'relaxed', 'acq_rel', 'acquire' or 'release' clause}} omp50-note at +1 {{'seq_cst' clause used here}} omp45-error at +1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
+#pragma omp atomic seq_cst relaxed
+  a += b;
+
+// omp45-error at +1 {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp atomic'}}
+#pragma omp atomic update relaxed
+  // 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}}
+  ;
+
+ return relaxed<int>(); // omp50-note {{in instantiation of function template specialization 'relaxed<int>' requested here}}
+}
+
 template <class T>
 T mixed() {
   T a, b = T();

diff  --git a/clang/test/OpenMP/atomic_read_codegen.c b/clang/test/OpenMP/atomic_read_codegen.c
index 8d49115bc603..94e212f72447 100644
--- a/clang/test/OpenMP/atomic_read_codegen.c
+++ b/clang/test/OpenMP/atomic_read_codegen.c
@@ -304,7 +304,7 @@ int main() {
 // CHECK: [[ASHR:%.+]] = ashr i8 [[SHL]], 7
 // CHECK: sext i8 [[ASHR]] to i32
 // CHECK: store x86_fp80
-#pragma omp atomic read
+#pragma omp atomic relaxed read
   ldv = bfx4_packed.a;
 // CHECK: [[LD:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @bfx4 to i64*) monotonic
 // CHECK: store i64 [[LD]], i64* [[LDTEMP:%.+]]
@@ -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
+#pragma omp atomic read relaxed
   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:%.+]]

diff  --git a/clang/test/OpenMP/atomic_update_codegen.cpp b/clang/test/OpenMP/atomic_update_codegen.cpp
index 7913dc1ce69f..a2b6f70540aa 100644
--- a/clang/test/OpenMP/atomic_update_codegen.cpp
+++ b/clang/test/OpenMP/atomic_update_codegen.cpp
@@ -809,7 +809,7 @@ int main() {
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-#pragma omp atomic update
+#pragma omp atomic relaxed update
   bfx4_packed.a -= ldv;
 // CHECK: [[EXPR:%.+]] = load x86_fp80, x86_fp80* @{{.+}}
 // CHECK: [[PREV_VALUE:%.+]] = load atomic i64, i64* bitcast (%struct.BitFields4* @{{.+}} to i64*) monotonic
@@ -866,7 +866,7 @@ int main() {
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-#pragma omp atomic update
+#pragma omp atomic update relaxed
   bfx4_packed.b += ldv;
 // CHECK: load i64, i64*
 // CHECK: [[EXPR:%.+]] = uitofp i64 %{{.+}} to float
@@ -890,7 +890,7 @@ int main() {
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-#pragma omp atomic
+#pragma omp atomic relaxed
   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 053f46d55246..3cbaf2752448 100644
--- a/clang/test/OpenMP/atomic_write_codegen.c
+++ b/clang/test/OpenMP/atomic_write_codegen.c
@@ -486,7 +486,7 @@ int main() {
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i8, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-#pragma omp atomic write
+#pragma omp atomic relaxed write
   bfx4_packed.b = ldv;
 // CHECK: load i64, i64*
 // CHECK: [[VEC_ITEM_VAL:%.+]] = uitofp i64 %{{.+}} to float
@@ -505,7 +505,7 @@ int main() {
 // CHECK: [[FAIL_SUCCESS:%.+]] = extractvalue { i64, i1 } [[RES]], 1
 // CHECK: br i1 [[FAIL_SUCCESS]], label %[[EXIT:.+]], label %[[CONT]]
 // CHECK: [[EXIT]]
-#pragma omp atomic write
+#pragma omp atomic write relaxed
   float2x.x = ulv;
 // CHECK: call i32 @llvm.read_register.i32(
 // CHECK: sitofp i32 %{{.+}} to double

diff  --git a/clang/test/OpenMP/flush_messages.cpp b/clang/test/OpenMP/flush_messages.cpp
index 48a70f3f8dcb..51497249a8f3 100644
--- a/clang/test/OpenMP/flush_messages.cpp
+++ b/clang/test/OpenMP/flush_messages.cpp
@@ -138,6 +138,8 @@ label1 : {
 #pragma omp flush acq_rel // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}}
 #pragma omp flush acquire // omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}}
 #pragma omp flush release // omp45-error {{unexpected OpenMP clause 'release' in directive '#pragma omp flush'}}
+#pragma omp flush relaxed // expected-error {{unexpected OpenMP clause 'relaxed' in directive '#pragma omp flush'}}
+#pragma omp flush seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp flush'}}
 #pragma omp flush acq_rel acquire // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel', 'acquire' or 'release' clause}} omp50-note {{'acq_rel' clause used here}}
 #pragma omp flush release acquire // omp45-error {{unexpected OpenMP clause 'release' in directive '#pragma omp flush'}} omp45-error {{unexpected OpenMP clause 'acquire' in directive '#pragma omp flush'}} omp50-error {{directive '#pragma omp flush' cannot contain more than one 'acq_rel', 'acquire' or 'release' clause}} omp50-note {{'release' clause used here}}
 #pragma omp flush acq_rel (argc) // omp45-error {{unexpected OpenMP clause 'acq_rel' in directive '#pragma omp flush'}} omp50-error {{'flush' directive with memory order clause 'acq_rel' cannot have the list}} omp50-note {{memory order clause 'acq_rel' is specified here}}

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 12479c7abb84..6f32240fe6e4 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2241,6 +2241,8 @@ void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
 
 void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
 
+void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
+
 void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
 
 void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}


        


More information about the cfe-commits mailing list