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 @@ -509,6 +509,7 @@ NODE(parser, OmpProcBindClause) NODE_ENUM(OmpProcBindClause, Type) NODE(parser, OmpReductionClause) + NODE(parser, OmpTaskReductionClause) NODE(parser, OmpReductionCombiner) NODE(OmpReductionCombiner, FunctionCombiner) NODE(parser, OmpReductionInitializerClause) 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 @@ -3419,9 +3419,13 @@ // variable-name-list) struct OmpReductionClause { TUPLE_CLASS_BOILERPLATE(OmpReductionClause); - std::tuple> t; + std::tuple t; }; +// [OMP-5.0] 2.19.5.5 task-reduction-clause -> +// TASK_REDUCTION (reduction-identifier: variable-name-list) +WRAPPER_CLASS(OmpTaskReductionClause, OmpReductionClause); + // OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list) struct OmpAllocateClause { TUPLE_CLASS_BOILERPLATE(OmpAllocateClause); 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 @@ -102,7 +102,10 @@ construct(Parser{})) TYPE_PARSER(construct( - Parser{} / ":", nonemptyList(designator))) + Parser{} / ":", Parser{})) + +//[OMP-5.0] 2.19.5.5 TASK_REDUCTION (reduction-identifier: variable-name-list) +TYPE_PARSER(construct(Parser{})) // OMP 5.0 2.11.4 ALLOCATE ([allocator:] variable-name-list) TYPE_PARSER(construct( @@ -218,6 +221,8 @@ construct(parenthesized(Parser{})) || "REDUCTION" >> construct(parenthesized(Parser{})) || + "TASK_REDUCTION" >> + construct(parenthesized(Parser{})) || "RELAXED" >> construct(construct()) || "RELEASE" >> construct(construct()) || "SAFELEN" >> construct(construct( 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 @@ -2007,9 +2007,13 @@ Word("REDUCTION("); Walk(std::get(x.t)); Put(":"); - Walk(std::get>(x.t), ","); + Walk(std::get(x.t)); Put(")"); } + void Unparse(const OmpTaskReductionClause &x) { + Word("TASK_REDUCTION("); + Walk(x.v); + } void Unparse(const OmpAllocateClause &x) { Word("ALLOCATE("); Walk(std::get>(x.t), ":"); 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 @@ -162,6 +162,7 @@ void Enter(const parser::OmpMapClause &); void Enter(const parser::OmpProcBindClause &); void Enter(const parser::OmpReductionClause &); + void Enter(const parser::OmpTaskReductionClause &); void Enter(const parser::OmpScheduleClause &); private: 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 @@ -414,6 +414,7 @@ CHECK_SIMPLE_PARSER_CLAUSE(OmpNowait, OMPC_nowait) CHECK_SIMPLE_PARSER_CLAUSE(OmpProcBindClause, OMPC_proc_bind) CHECK_SIMPLE_PARSER_CLAUSE(OmpReductionClause, OMPC_reduction) +CHECK_SIMPLE_PARSER_CLAUSE(OmpTaskReductionClause, OMPC_task_reduction) // Restrictions specific to each clause are implemented apart from the // generalized restrictions. 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 @@ -349,7 +349,8 @@ ! collapse-clause a = 0.0 - !$omp simd private(b) reduction(+:a) + !ERROR: TASK_REDUCTION clause is not allowed on the SIMD directive + !$omp simd private(b) reduction(+:a) task_reduction(+:a) do i = 1, N a = a + b + 3.14 enddo @@ -449,7 +450,8 @@ enddo !ERROR: At most one NUM_TASKS clause can appear on the TASKLOOP directive - !$omp taskloop num_tasks(3) num_tasks(2) + !ERROR: TASK_REDUCTION clause is not allowed on the TASKLOOP directive + !$omp taskloop num_tasks(3) num_tasks(2) task_reduction(*:a) do i = 1,N a = 3.14 enddo diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -232,6 +232,7 @@ } def OMPC_TaskReduction : Clause<"task_reduction"> { let clangClass = "OMPTaskReductionClause"; + let flangClass = "OmpTaskReductionClause"; } def OMPC_InReduction : Clause<"in_reduction"> { let clangClass = "OMPInReductionClause";