[flang-commits] [flang] 4536c6a - [flang][OpenMP] Enhance parser support for atomic construct to OpenMP 5.0

Kiran Kumar T P via flang-commits flang-commits at lists.llvm.org
Mon Sep 7 18:22:24 PDT 2020


Author: Kiran Kumar T P
Date: 2020-09-08T06:52:07+05:30
New Revision: 4536c6acb3809eaadc836f24f091db1b50b82af9

URL: https://github.com/llvm/llvm-project/commit/4536c6acb3809eaadc836f24f091db1b50b82af9
DIFF: https://github.com/llvm/llvm-project/commit/4536c6acb3809eaadc836f24f091db1b50b82af9.diff

LOG: [flang][OpenMP] Enhance parser support for atomic construct to OpenMP 5.0

Summary:
This patch enhances parser support for atomic construct to OpenMP 5.0.
2.17.7 atomic -> ATOMIC [clause [,]] atomic-clause [[,] clause] |
                 ATOMIC [clause]
       clause -> memory-order-clause | HINT(hint-expression)
       memory-order-clause -> SEQ_CST | ACQ_REL | RELEASE | ACQUIRE | RELAXED
       atomic-clause -> READ | WRITE | UPDATE | CAPTURE

The patch includes code changes and testcase modifications.

Reviewed By: DavidTruby, kiranchandramohan, sameeranjoshi

Differential Revision: https://reviews.llvm.org/D82931

Added: 
    

Modified: 
    flang/docs/OpenMP-4.5-grammar.txt
    flang/include/flang/Parser/dump-parse-tree.h
    flang/include/flang/Parser/parse-tree.h
    flang/lib/Parser/openmp-parsers.cpp
    flang/lib/Parser/unparse.cpp
    flang/test/Semantics/omp-atomic.f90

Removed: 
    


################################################################################
diff  --git a/flang/docs/OpenMP-4.5-grammar.txt b/flang/docs/OpenMP-4.5-grammar.txt
index c74072ba1ef2..180494bbf509 100644
--- a/flang/docs/OpenMP-4.5-grammar.txt
+++ b/flang/docs/OpenMP-4.5-grammar.txt
@@ -344,6 +344,8 @@
                  ATOMIC [seq_cst]
        atomic-clause -> READ | WRITE | UPDATE | CAPTURE
 
+2.13.6 end-atomic -> END ATOMIC
+
 2.13.7 flush -> FLUSH [(variable-name-list)]
 
 2.13.8 ordered -> ORDERED ordered-construct-clause [[[,] ordered-construct-clause]...]

diff  --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 41ff9631d101..921e6172bf89 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -445,6 +445,9 @@ class ParseTreeDumper {
   NODE(parser, OmpAtomicCapture)
   NODE(OmpAtomicCapture, Stmt1)
   NODE(OmpAtomicCapture, Stmt2)
+  NODE(parser, OmpAtomicMemoryOrderClause)
+  NODE(parser, OmpAtomicMemoryOrderClauseList)
+  NODE(parser, OmpAtomicMemoryOrderClausePostList)
   NODE(parser, OmpAtomicRead)
   NODE(parser, OmpAtomicUpdate)
   NODE(parser, OmpAtomicWrite)
@@ -464,7 +467,6 @@ class ParseTreeDumper {
 #include "llvm/Frontend/OpenMP/OMP.cpp.inc"
   NODE(parser, OmpClauseList)
   NODE(parser, OmpCriticalDirective)
-  NODE(OmpCriticalDirective, Hint)
   NODE(parser, OmpDeclareTargetSpecifier)
   NODE(parser, OmpDeclareTargetWithClause)
   NODE(parser, OmpDeclareTargetWithList)
@@ -487,6 +489,7 @@ class ParseTreeDumper {
   NODE(parser, OmpEndCriticalDirective)
   NODE(parser, OmpEndLoopDirective)
   NODE(parser, OmpEndSectionsDirective)
+  NODE(parser, OmpHintExpr)
   NODE(parser, OmpIfClause)
   NODE_ENUM(OmpIfClause, DirectiveNameModifier)
   NODE(parser, OmpLinearClause)
@@ -499,10 +502,12 @@ class ParseTreeDumper {
   NODE(parser, OmpMapType)
   NODE(OmpMapType, Always)
   NODE_ENUM(OmpMapType, Type)
-  NODE(parser, OmpMemoryClause)
-  NODE_ENUM(OmpMemoryClause, MemoryOrder)
-  NODE(parser, OmpMemoryClauseList)
-  NODE(parser, OmpMemoryClausePostList)
+  NODE(parser, OmpMemoryOrderClause)
+  static std::string GetNodeName(const llvm::omp::Clause &x) {
+    return llvm::Twine(
+        "llvm::omp::Clause = ", llvm::omp::getOpenMPClauseName(x))
+        .str();
+  }
   NODE(parser, OmpNowait)
   NODE(parser, OmpObject)
   NODE(parser, OmpObjectList)
@@ -549,7 +554,6 @@ class ParseTreeDumper {
   NODE(parser, OpenMPDeclareSimdConstruct)
   NODE(parser, OpenMPDeclareTargetConstruct)
   NODE(parser, OmpFlushMemoryClause)
-  NODE_ENUM(OmpFlushMemoryClause, FlushMemoryOrder)
   NODE(parser, OpenMPFlushConstruct)
   NODE(parser, OpenMPLoopConstruct)
   NODE(parser, OpenMPSimpleStandaloneConstruct)

diff  --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 166e573b5cec..a9fb92cf2584 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3591,12 +3591,14 @@ struct OpenMPDeclarativeConstruct {
       u;
 };
 
+// HINT(hint-expression)
+WRAPPER_CLASS(OmpHintExpr, ConstantExpr);
+
 // 2.13.2 CRITICAL [Name] <block> END CRITICAL [Name]
 struct OmpCriticalDirective {
   TUPLE_CLASS_BOILERPLATE(OmpCriticalDirective);
-  WRAPPER_CLASS(Hint, ConstantExpr);
   CharBlock source;
-  std::tuple<Verbatim, std::optional<Name>, std::optional<Hint>> t;
+  std::tuple<Verbatim, std::optional<Name>, std::optional<OmpHintExpr>> t;
 };
 struct OmpEndCriticalDirective {
   TUPLE_CLASS_BOILERPLATE(OmpEndCriticalDirective);
@@ -3608,44 +3610,56 @@ struct OpenMPCriticalConstruct {
   std::tuple<OmpCriticalDirective, Block, OmpEndCriticalDirective> t;
 };
 
-// 2.13.6 atomic -> ATOMIC [seq_cst[,]] atomic-clause [[,]seq_cst] |
-//                  ATOMIC [seq_cst]
+// 2.17.7 atomic -> ATOMIC [clause[,]] atomic-clause [[,]clause] |
+//                  ATOMIC [clause]
+//        clause -> memory-order-clause | HINT(hint-expression)
+//        memory-order-clause -> SEQ_CST | ACQ_REL | RELEASE | ACQUIRE | RELAXED
 //        atomic-clause -> READ | WRITE | UPDATE | CAPTURE
 
 // END ATOMIC
 EMPTY_CLASS(OmpEndAtomic);
 
-// ATOMIC Memory related clause
-struct OmpMemoryClause {
-  ENUM_CLASS(MemoryOrder, SeqCst)
-  WRAPPER_CLASS_BOILERPLATE(OmpMemoryClause, MemoryOrder);
+// Memory order clause
+struct OmpMemoryOrderClause {
+  WRAPPER_CLASS_BOILERPLATE(OmpMemoryOrderClause, llvm::omp::Clause);
   CharBlock source;
 };
 
-WRAPPER_CLASS(OmpMemoryClauseList, std::list<OmpMemoryClause>);
-WRAPPER_CLASS(OmpMemoryClausePostList, std::list<OmpMemoryClause>);
+// ATOMIC Memory order clause or hint expression
+struct OmpAtomicMemoryOrderClause {
+  UNION_CLASS_BOILERPLATE(OmpAtomicMemoryOrderClause);
+  std::variant<OmpMemoryOrderClause, OmpHintExpr> u;
+};
+
+WRAPPER_CLASS(
+    OmpAtomicMemoryOrderClauseList, std::list<OmpAtomicMemoryOrderClause>);
+WRAPPER_CLASS(
+    OmpAtomicMemoryOrderClausePostList, std::list<OmpAtomicMemoryOrderClause>);
 
 // ATOMIC READ
 struct OmpAtomicRead {
   TUPLE_CLASS_BOILERPLATE(OmpAtomicRead);
-  std::tuple<OmpMemoryClauseList, Verbatim, OmpMemoryClausePostList,
-      Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
+  std::tuple<OmpAtomicMemoryOrderClauseList, Verbatim,
+      OmpAtomicMemoryOrderClausePostList, Statement<AssignmentStmt>,
+      std::optional<OmpEndAtomic>>
       t;
 };
 
 // ATOMIC WRITE
 struct OmpAtomicWrite {
   TUPLE_CLASS_BOILERPLATE(OmpAtomicWrite);
-  std::tuple<OmpMemoryClauseList, Verbatim, OmpMemoryClausePostList,
-      Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
+  std::tuple<OmpAtomicMemoryOrderClauseList, Verbatim,
+      OmpAtomicMemoryOrderClausePostList, Statement<AssignmentStmt>,
+      std::optional<OmpEndAtomic>>
       t;
 };
 
 // ATOMIC UPDATE
 struct OmpAtomicUpdate {
   TUPLE_CLASS_BOILERPLATE(OmpAtomicUpdate);
-  std::tuple<OmpMemoryClauseList, Verbatim, OmpMemoryClausePostList,
-      Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
+  std::tuple<OmpAtomicMemoryOrderClauseList, Verbatim,
+      OmpAtomicMemoryOrderClausePostList, Statement<AssignmentStmt>,
+      std::optional<OmpEndAtomic>>
       t;
 };
 
@@ -3654,16 +3668,16 @@ struct OmpAtomicCapture {
   TUPLE_CLASS_BOILERPLATE(OmpAtomicCapture);
   WRAPPER_CLASS(Stmt1, Statement<AssignmentStmt>);
   WRAPPER_CLASS(Stmt2, Statement<AssignmentStmt>);
-  std::tuple<OmpMemoryClauseList, Verbatim, OmpMemoryClausePostList, Stmt1,
-      Stmt2, OmpEndAtomic>
+  std::tuple<OmpAtomicMemoryOrderClauseList, Verbatim,
+      OmpAtomicMemoryOrderClausePostList, Stmt1, Stmt2, OmpEndAtomic>
       t;
 };
 
 // ATOMIC
 struct OmpAtomic {
   TUPLE_CLASS_BOILERPLATE(OmpAtomic);
-  std::tuple<Verbatim, OmpMemoryClauseList, Statement<AssignmentStmt>,
-      std::optional<OmpEndAtomic>>
+  std::tuple<Verbatim, OmpAtomicMemoryOrderClauseList,
+      Statement<AssignmentStmt>, std::optional<OmpEndAtomic>>
       t;
 };
 
@@ -3707,8 +3721,7 @@ struct OpenMPCancelConstruct {
 //                        release
 //                        acquire
 struct OmpFlushMemoryClause {
-  ENUM_CLASS(FlushMemoryOrder, AcqRel, Release, Acquire)
-  WRAPPER_CLASS_BOILERPLATE(OmpFlushMemoryClause, FlushMemoryOrder);
+  WRAPPER_CLASS_BOILERPLATE(OmpFlushMemoryClause, llvm::omp::Clause);
   CharBlock source;
 };
 

diff  --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index cd5ee0de556d..a7f4a1ae492c 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -300,9 +300,9 @@ TYPE_PARSER(sourced(construct<OpenMPCancelConstruct>(verbatim("CANCEL"_tok),
 //                               release
 //                               acquire
 TYPE_PARSER(sourced(construct<OmpFlushMemoryClause>(
-    "ACQ_REL" >> pure(OmpFlushMemoryClause::FlushMemoryOrder::AcqRel) ||
-    "RELEASE" >> pure(OmpFlushMemoryClause::FlushMemoryOrder::Release) ||
-    "ACQUIRE" >> pure(OmpFlushMemoryClause::FlushMemoryOrder::Acquire))))
+    "ACQ_REL" >> pure(llvm::omp::Clause::OMPC_acq_rel) ||
+    "RELEASE" >> pure(llvm::omp::Clause::OMPC_release) ||
+    "ACQUIRE" >> pure(llvm::omp::Clause::OMPC_acquire))))
 
 TYPE_PARSER(sourced(construct<OpenMPFlushConstruct>(verbatim("FLUSH"_tok),
     maybe(Parser<OmpFlushMemoryClause>{}),
@@ -384,51 +384,74 @@ TYPE_PARSER(construct<OmpReductionCombiner>(Parser<AssignmentStmt>{}) ||
             construct<Call>(Parser<ProcedureDesignator>{},
                 parenthesized(optionalList(actualArgSpec))))))
 
-// 2.13.6 ATOMIC [seq_cst[,]] atomic-clause [[,]seq_cst] | ATOMIC [seq_cst]
-//        atomic-clause -> READ | WRITE | UPDATE | CAPTURE
+// Hint Expression => HINT(hint-expression)
+TYPE_PARSER("HINT" >> construct<OmpHintExpr>(parenthesized(constantExpr)))
+
+// 2.17.7 atomic -> ATOMIC [clause [,]] atomic-clause [[,] clause] |
+//                  ATOMIC [clause]
+//       clause -> memory-order-clause | HINT(hint-expression)
+//       memory-order-clause -> SEQ_CST | ACQ_REL | RELEASE | ACQUIRE | RELAXED
+//       atomic-clause -> READ | WRITE | UPDATE | CAPTURE
 
 // OMP END ATOMIC
 TYPE_PARSER(construct<OmpEndAtomic>(startOmpLine >> "END ATOMIC"_tok))
 
-// ATOMIC Memory related clause
-TYPE_PARSER(sourced(construct<OmpMemoryClause>(
-    "SEQ_CST" >> pure(OmpMemoryClause::MemoryOrder::SeqCst))))
+// Memory order clause
+TYPE_PARSER(sourced(construct<OmpMemoryOrderClause>(
+    "SEQ_CST" >> pure(llvm::omp::Clause::OMPC_seq_cst) ||
+    "ACQ_REL" >> pure(llvm::omp::Clause::OMPC_acq_rel) ||
+    "RELEASE" >> pure(llvm::omp::Clause::OMPC_release) ||
+    "ACQUIRE" >> pure(llvm::omp::Clause::OMPC_acquire) ||
+    "RELAXED" >> pure(llvm::omp::Clause::OMPC_relaxed))))
 
-// ATOMIC Memory Clause List
-TYPE_PARSER(construct<OmpMemoryClauseList>(
-    many(maybe(","_tok) >> Parser<OmpMemoryClause>{})))
+// ATOMIC Memory order clause or Hint expression
+TYPE_PARSER(
+    construct<OmpAtomicMemoryOrderClause>(Parser<OmpMemoryOrderClause>{}) ||
+    construct<OmpAtomicMemoryOrderClause>(Parser<OmpHintExpr>{}))
 
-TYPE_PARSER(construct<OmpMemoryClausePostList>(
-    many(maybe(","_tok) >> Parser<OmpMemoryClause>{})))
+// ATOMIC Memory order Clause List
+TYPE_PARSER(construct<OmpAtomicMemoryOrderClauseList>(
+    many(maybe(","_tok) >> Parser<OmpAtomicMemoryOrderClause>{})))
 
-// OMP [SEQ_CST] ATOMIC READ [SEQ_CST]
-TYPE_PARSER("ATOMIC" >>
-    construct<OmpAtomicRead>(Parser<OmpMemoryClauseList>{} / maybe(","_tok),
-        verbatim("READ"_tok), Parser<OmpMemoryClausePostList>{} / endOmpLine,
-        statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
+TYPE_PARSER(construct<OmpAtomicMemoryOrderClausePostList>(
+    many(maybe(","_tok) >> Parser<OmpAtomicMemoryOrderClause>{})))
 
-// OMP ATOMIC [SEQ_CST] CAPTURE [SEQ_CST]
+// OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] READ [MEMORY-ORDER-CLAUSE-LIST]
 TYPE_PARSER("ATOMIC" >>
-    construct<OmpAtomicCapture>(Parser<OmpMemoryClauseList>{} / maybe(","_tok),
-        verbatim("CAPTURE"_tok), Parser<OmpMemoryClausePostList>{} / endOmpLine,
-        statement(assignmentStmt), statement(assignmentStmt),
-        Parser<OmpEndAtomic>{} / endOmpLine))
+    construct<OmpAtomicRead>(
+        Parser<OmpAtomicMemoryOrderClauseList>{} / maybe(","_tok),
+        verbatim("READ"_tok),
+        Parser<OmpAtomicMemoryOrderClausePostList>{} / endOmpLine,
+        statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
 
-// OMP ATOMIC [SEQ_CST] UPDATE [SEQ_CST]
+// OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] CAPTURE [MEMORY-ORDER-CLAUSE-LIST]
+TYPE_PARSER(
+    "ATOMIC" >> construct<OmpAtomicCapture>(
+                    Parser<OmpAtomicMemoryOrderClauseList>{} / maybe(","_tok),
+                    verbatim("CAPTURE"_tok),
+                    Parser<OmpAtomicMemoryOrderClausePostList>{} / endOmpLine,
+                    statement(assignmentStmt), statement(assignmentStmt),
+                    Parser<OmpEndAtomic>{} / endOmpLine))
+
+// OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] UPDATE [MEMORY-ORDER-CLAUSE-LIST]
 TYPE_PARSER("ATOMIC" >>
-    construct<OmpAtomicUpdate>(Parser<OmpMemoryClauseList>{} / maybe(","_tok),
-        verbatim("UPDATE"_tok), Parser<OmpMemoryClausePostList>{} / endOmpLine,
+    construct<OmpAtomicUpdate>(
+        Parser<OmpAtomicMemoryOrderClauseList>{} / maybe(","_tok),
+        verbatim("UPDATE"_tok),
+        Parser<OmpAtomicMemoryOrderClausePostList>{} / endOmpLine,
         statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
 
-// OMP ATOMIC [SEQ_CST]
+// OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST]
 TYPE_PARSER(construct<OmpAtomic>(verbatim("ATOMIC"_tok),
-    Parser<OmpMemoryClauseList>{} / endOmpLine, statement(assignmentStmt),
-    maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
+    Parser<OmpAtomicMemoryOrderClauseList>{} / endOmpLine,
+    statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
 
-// ATOMIC [SEQ_CST] WRITE [SEQ_CST]
+// OMP ATOMIC [MEMORY-ORDER-CLAUSE-LIST] WRITE [MEMORY-ORDER-CLAUSE-LIST]
 TYPE_PARSER("ATOMIC" >>
-    construct<OmpAtomicWrite>(Parser<OmpMemoryClauseList>{} / maybe(","_tok),
-        verbatim("WRITE"_tok), Parser<OmpMemoryClausePostList>{} / endOmpLine,
+    construct<OmpAtomicWrite>(
+        Parser<OmpAtomicMemoryOrderClauseList>{} / maybe(","_tok),
+        verbatim("WRITE"_tok),
+        Parser<OmpAtomicMemoryOrderClausePostList>{} / endOmpLine,
         statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
 
 // Atomic Construct
@@ -444,9 +467,7 @@ TYPE_PARSER(startOmpLine >>
         verbatim("END CRITICAL"_tok), maybe(parenthesized(name)))) /
         endOmpLine)
 TYPE_PARSER(sourced(construct<OmpCriticalDirective>(verbatim("CRITICAL"_tok),
-                maybe(parenthesized(name)),
-                maybe("HINT" >> construct<OmpCriticalDirective::Hint>(
-                                    parenthesized(constantExpr))))) /
+                maybe(parenthesized(name)), maybe(Parser<OmpHintExpr>{}))) /
     endOmpLine)
 
 TYPE_PARSER(construct<OpenMPCriticalConstruct>(

diff  --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index e26795d0825b..ab94aa2e00c2 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2222,19 +2222,36 @@ class UnparseVisitor {
       break;
     }
   }
-  void Unparse(const OmpMemoryClause &x) {
+  void Unparse(const OmpHintExpr &x) { Word("HINT("), Walk(x.v), Put(')'); }
+  void Unparse(const OmpMemoryOrderClause &x) {
     switch (x.v) {
-    case OmpMemoryClause::MemoryOrder::SeqCst:
+    case llvm::omp::Clause::OMPC_seq_cst:
       Word("SEQ_CST");
       break;
+    case llvm::omp::Clause::OMPC_acq_rel:
+      Word("ACQ_REL");
+      break;
+    case llvm::omp::Clause::OMPC_release:
+      Word("RELEASE");
+      break;
+    case llvm::omp::Clause::OMPC_acquire:
+      Word("ACQUIRE");
+      break;
+    case llvm::omp::Clause::OMPC_relaxed:
+      Word("RELAXED");
+      break;
+    default:
+      break;
     }
   }
-  void Unparse(const OmpMemoryClauseList &x) { Walk(" ", x.v, " "); }
-  void Unparse(const OmpMemoryClausePostList &x) { Walk(" ", x.v, " "); }
+  void Unparse(const OmpAtomicMemoryOrderClauseList &x) { Walk(" ", x.v, " "); }
+  void Unparse(const OmpAtomicMemoryOrderClausePostList &x) {
+    Walk(" ", x.v, " ");
+  }
   void Unparse(const OmpAtomic &x) {
     BeginOpenMP();
     Word("!$OMP ATOMIC");
-    Walk(std::get<OmpMemoryClauseList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClauseList>(x.t));
     Put("\n");
     EndOpenMP();
     Walk(std::get<Statement<AssignmentStmt>>(x.t));
@@ -2245,9 +2262,9 @@ class UnparseVisitor {
   void Unparse(const OmpAtomicCapture &x) {
     BeginOpenMP();
     Word("!$OMP ATOMIC");
-    Walk(std::get<OmpMemoryClauseList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClauseList>(x.t));
     Word(" CAPTURE");
-    Walk(std::get<OmpMemoryClausePostList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClausePostList>(x.t));
     Put("\n");
     EndOpenMP();
     Walk(std::get<OmpAtomicCapture::Stmt1>(x.t));
@@ -2260,9 +2277,9 @@ class UnparseVisitor {
   void Unparse(const OmpAtomicRead &x) {
     BeginOpenMP();
     Word("!$OMP ATOMIC");
-    Walk(std::get<OmpMemoryClauseList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClauseList>(x.t));
     Word(" READ");
-    Walk(std::get<OmpMemoryClausePostList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClausePostList>(x.t));
     Put("\n");
     EndOpenMP();
     Walk(std::get<Statement<AssignmentStmt>>(x.t));
@@ -2273,9 +2290,9 @@ class UnparseVisitor {
   void Unparse(const OmpAtomicUpdate &x) {
     BeginOpenMP();
     Word("!$OMP ATOMIC");
-    Walk(std::get<OmpMemoryClauseList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClauseList>(x.t));
     Word(" UPDATE");
-    Walk(std::get<OmpMemoryClausePostList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClausePostList>(x.t));
     Put("\n");
     EndOpenMP();
     Walk(std::get<Statement<AssignmentStmt>>(x.t));
@@ -2286,9 +2303,9 @@ class UnparseVisitor {
   void Unparse(const OmpAtomicWrite &x) {
     BeginOpenMP();
     Word("!$OMP ATOMIC");
-    Walk(std::get<OmpMemoryClauseList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClauseList>(x.t));
     Word(" WRITE");
-    Walk(std::get<OmpMemoryClausePostList>(x.t));
+    Walk(std::get<OmpAtomicMemoryOrderClausePostList>(x.t));
     Put("\n");
     EndOpenMP();
     Walk(std::get<Statement<AssignmentStmt>>(x.t));
@@ -2300,8 +2317,7 @@ class UnparseVisitor {
     BeginOpenMP();
     Word("!$OMP CRITICAL");
     Walk(" (", std::get<std::optional<Name>>(x.t), ")");
-    Walk(" HINT(", std::get<std::optional<OmpCriticalDirective::Hint>>(x.t),
-        ")");
+    Walk(std::get<std::optional<OmpHintExpr>>(x.t));
     Put("\n");
     EndOpenMP();
   }
@@ -2431,15 +2447,17 @@ class UnparseVisitor {
   }
   void Unparse(const OmpFlushMemoryClause &x) {
     switch (x.v) {
-    case OmpFlushMemoryClause::FlushMemoryOrder::AcqRel:
+    case llvm::omp::Clause::OMPC_acq_rel:
       Word("ACQ_REL ");
       break;
-    case OmpFlushMemoryClause::FlushMemoryOrder::Release:
+    case llvm::omp::Clause::OMPC_release:
       Word("RELEASE ");
       break;
-    case OmpFlushMemoryClause::FlushMemoryOrder::Acquire:
+    case llvm::omp::Clause::OMPC_acquire:
       Word("ACQUIRE ");
       break;
+    default:
+      break;
     }
   }
   void Unparse(const OpenMPFlushConstruct &x) {

diff  --git a/flang/test/Semantics/omp-atomic.f90 b/flang/test/Semantics/omp-atomic.f90
index d5cb87aaba32..8d3f95a77045 100644
--- a/flang/test/Semantics/omp-atomic.f90
+++ b/flang/test/Semantics/omp-atomic.f90
@@ -1,5 +1,5 @@
 ! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
-
+use omp_lib
 ! Check OpenMP 2.13.6 atomic Construct
 
   a = 1.0
@@ -11,12 +11,32 @@
   a = b
   !$omp end atomic
 
+  !$omp atomic read acquire hint(OMP_LOCK_HINT_CONTENDED)
+  a = b
+
+  !$omp atomic release hint(OMP_LOCK_HINT_UNCONTENDED) write
+  a = b
+
   !$omp atomic capture seq_cst
   b = a
   a = a + 1
   !$omp end atomic
 
+  !$omp atomic hint(1) acq_rel capture
+  b = a
+  a = a + 1
+  !$omp end atomic
+
+  !ERROR: expected end of line
+  !ERROR: expected end of line
+  !$omp atomic read write
+  a = a + 1
+
   !$omp atomic
   a = a + 1
+
+  !$omp atomic relaxed
+  a = a + 1
+
   !$omp end parallel
 end


        


More information about the flang-commits mailing list