diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -548,7 +548,7 @@ NODE(parser, OpenMPDeclareReductionConstruct) NODE(parser, OpenMPDeclareSimdConstruct) NODE(parser, OpenMPDeclareTargetConstruct) - NODE(parser, OmpFlushMemoryClause) + NODE(parser, OmpMemoryOrderClause) 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 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3701,8 +3701,8 @@ // memory-order-clause -> acq_rel // release // acquire -struct OmpFlushMemoryClause { - WRAPPER_CLASS_BOILERPLATE(OmpFlushMemoryClause, llvm::omp::Clause); +struct OmpMemoryOrderClause { + WRAPPER_CLASS_BOILERPLATE(OmpMemoryOrderClause, OmpClause); CharBlock source; }; @@ -3710,7 +3710,7 @@ struct OpenMPFlushConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct); CharBlock source; - std::tuple, + std::tuple, std::optional> t; }; diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -109,9 +109,9 @@ std::get>( flushConstruct.t)) genObjectList(*ompObjectList, converter, operandRange); - if (std::get>( + if (std::get>( flushConstruct.t)) - TODO("Handle OmpFlushMemoryClause"); + TODO("Handle OmpMemoryOrderClause"); converter.getFirOpBuilder().create( converter.getCurrentLocation(), operandRange); }, diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -302,18 +302,22 @@ TYPE_PARSER(sourced(construct(verbatim("CANCEL"_tok), Parser{}, maybe("IF" >> parenthesized(scalarLogicalExpr))))) -// 2.17.8 Flush construct [OpenMP 5.0] -// flush -> FLUSH [memory-order-clause] [(variable-name-list)] -// memory-order-clause -> acq_rel +// 2.17.7 Atomtic construct/2.17.8 Flush construct [OpenMP 5.0] +// memory-order-clause -> +// seq_cst +// acq_rel // release // acquire -TYPE_PARSER(sourced(construct( - "ACQ_REL" >> pure(llvm::omp::Clause::OMPC_acq_rel) || - "RELEASE" >> pure(llvm::omp::Clause::OMPC_release) || - "ACQUIRE" >> pure(llvm::omp::Clause::OMPC_acquire)))) +// relaxed +TYPE_PARSER(sourced(construct( + sourced("SEQ_CST" >> construct(construct()) || + "ACQ_REL" >> construct(construct()) || + "RELEASE" >> construct(construct()) || + "ACQUIRE" >> construct(construct()) || + "RELAXED" >> construct(construct()))))) TYPE_PARSER(sourced(construct(verbatim("FLUSH"_tok), - maybe(Parser{}), + maybe(Parser{}), maybe(parenthesized(Parser{}))))) // Simple Standalone Directives diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2419,25 +2419,11 @@ Put("\n"); EndOpenMP(); } - void Unparse(const OmpFlushMemoryClause &x) { - switch (x.v) { - 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; - default: - break; - } - } + void Unparse(const OmpMemoryOrderClause &x) { Walk(x.v); } void Unparse(const OpenMPFlushConstruct &x) { BeginOpenMP(); Word("!$OMP FLUSH "); - Walk(std::get>(x.t)); + Walk(std::get>(x.t)); Walk(" (", std::get>(x.t), ")"); Put("\n"); EndOpenMP(); diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -150,6 +150,12 @@ void Enter(const parser::OmpClause::Uniform &); void Enter(const parser::OmpClause::UseDevicePtr &); void Enter(const parser::OmpClause::IsDevicePtr &); + // Memory-order-clause + void Enter(const parser::OmpClause::SeqCst &); + void Enter(const parser::OmpClause::AcqRel &); + void Enter(const parser::OmpClause::Release &); + void Enter(const parser::OmpClause::Acquire &); + void Enter(const parser::OmpClause::Relaxed &); void Enter(const parser::OmpAlignedClause &); void Enter(const parser::OmpAllocateClause &); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -378,6 +378,11 @@ CHECK_SIMPLE_CLAUSE(Uniform, OMPC_uniform) CHECK_SIMPLE_CLAUSE(Untied, OMPC_untied) CHECK_SIMPLE_CLAUSE(UseDevicePtr, OMPC_use_device_ptr) +CHECK_SIMPLE_CLAUSE(AcqRel, OMPC_acq_rel) +CHECK_SIMPLE_CLAUSE(Acquire, OMPC_acquire) +CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst) +CHECK_SIMPLE_CLAUSE(Release, OMPC_release) +CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed) CHECK_REQ_SCALAR_INT_CLAUSE(Grainsize, OMPC_grainsize) CHECK_REQ_SCALAR_INT_CLAUSE(NumTasks, OMPC_num_tasks) diff --git a/flang/test/Semantics/omp-clause-validity01.f90 b/flang/test/Semantics/omp-clause-validity01.f90 --- a/flang/test/Semantics/omp-clause-validity01.f90 +++ b/flang/test/Semantics/omp-clause-validity01.f90 @@ -62,7 +62,7 @@ a = 3.14 enddo !$omp end parallel - + !$omp task private(b) allocate(b) do i = 1, N z = 2 @@ -80,7 +80,7 @@ z = 2 end do !$omp end target - + !ERROR: ALLOCATE clause is not allowed on the TARGET DATA directive !$omp target data map(from: b) allocate(b) do i = 1, N @@ -488,6 +488,11 @@ !$omp flush release !$omp flush acquire !$omp flush release (c) + !ERROR: SEQ_CST clause is not allowed on the FLUSH directive + !$omp flush seq_cst + !ERROR: RELAXED clause is not allowed on the FLUSH directive + !$omp flush relaxed + !$omp cancel DO !$omp cancellation point parallel