diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index b07e89d201d198f..4de5ecf187a4cbe 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -2867,6 +2867,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u)) { std::string name = diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 95b962f5daf57cd..5fbe8f8a577cfdd 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -213,6 +213,29 @@ class AssociatedLoopChecker { std::map constructNamesAndLevels_; }; +// `OmpDesignatorChecker` is used to check if the designator +// can appear within the OpenMP construct +class OmpDesignatorChecker { +public: + OmpDesignatorChecker(SemanticsContext &context) : context_{context} {} + + template bool Pre(const T &) { return true; } + template void Post(const T &) {} + + bool Pre(const parser::Name &name) { + if (name.symbol->test(Symbol::Flag::OmpThreadprivate)) { + // OpenMP 5.2: 5.2 threadprivate directive restriction + context_.Say(name.source, + "A THREADPRIVATE variable `%s` cannot appear in a UNTIED TASK region"_err_en_US, + name.source); + } + return true; + } + +private: + SemanticsContext &context_; +}; + bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) { unsigned version{context_.langOptions().OpenMPVersion}; DirectiveContext &dirCtx = GetContext(); @@ -1164,6 +1187,16 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { HasInvalidWorksharingNesting( beginDir.source, llvm::omp::nestedWorkshareErrSet); break; + case llvm::omp::Directive::OMPD_task: { + const auto &clauses{std::get(beginBlockDir.t)}; + for (const auto &clause : clauses.v) { + if (std::get_if(&clause.u)) { + OmpDesignatorChecker ompDesignatorChecker{context_}; + parser::Walk(block, ompDesignatorChecker); + } + } + break; + } default: break; } diff --git a/flang/test/Lower/OpenMP/Todo/task_untied.f90 b/flang/test/Lower/OpenMP/Todo/task_untied.f90 deleted file mode 100644 index 87d242ba3e9d21f..000000000000000 --- a/flang/test/Lower/OpenMP/Todo/task_untied.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s - -!=============================================================================== -! `untied` clause -!=============================================================================== - -! CHECK: not yet implemented: UNTIED clause is not implemented yet -subroutine omp_task_untied() - !$omp task untied - call foo() - !$omp end task -end subroutine omp_task_untied diff --git a/flang/test/Lower/OpenMP/task.f90 b/flang/test/Lower/OpenMP/task.f90 index 6e525a044b011ee..a8cc16c540c9c85 100644 --- a/flang/test/Lower/OpenMP/task.f90 +++ b/flang/test/Lower/OpenMP/task.f90 @@ -235,6 +235,10 @@ subroutine task_multiple_clauses() !$omp end task end subroutine task_multiple_clauses +!=============================================================================== +! `mergeable` clause +!=============================================================================== + subroutine task_mergeable() !CHECK: omp.task mergeable { !CHECK: omp.terminator @@ -242,3 +246,16 @@ subroutine task_mergeable() !$omp task mergeable !$omp end task end subroutine + +!=============================================================================== +! `untied` clause +!=============================================================================== + +!CHECK-LABEL: func.func @_QPomp_task_untied() { +subroutine omp_task_untied() + !CHECK: omp.task untied { + !$omp task untied + call foo() + !CHECK: omp.terminator + !$omp end task +end subroutine omp_task_untied diff --git a/flang/test/Semantics/OpenMP/task-united01.f90 b/flang/test/Semantics/OpenMP/task-united01.f90 new file mode 100644 index 000000000000000..11227c0e919aa5c --- /dev/null +++ b/flang/test/Semantics/OpenMP/task-united01.f90 @@ -0,0 +1,28 @@ +! RUN: %python %S/../test_errors.py %s %flang %openmp_flags +! +! OpenMP 5.2: 5.2 threadprivate directive restriction + +subroutine task_united01() + integer, save :: var_01, var_02(2) + real :: var_03 + common /c/ var_03 + + !$omp threadprivate(var_01, var_02) + !$omp threadprivate(/c/) + + !$omp task untied + !ERROR: A THREADPRIVATE variable `var_01` cannot appear in a UNTIED TASK region + var_01 = 10 + !ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region + !ERROR: A THREADPRIVATE variable `var_01` cannot appear in a UNTIED TASK region + var_02(1) = sum([var_01, 20]) + !$omp end task + + !$omp task untied + !ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region + !ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region + var_02(2) = product(var_02) + !ERROR: A THREADPRIVATE variable `var_03` cannot appear in a UNTIED TASK region + var_03 = 3.14 + !$omp end task +end subroutine task_united01 diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp index 060113c41232412..d591c98a5497f86 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp @@ -258,7 +258,6 @@ static LogicalResult checkImplementationStatus(Operation &op) { checkAllocate(op, result); checkInReduction(op, result); checkPriority(op, result); - checkUntied(op, result); }) .Case([&](omp::TaskgroupOp op) { checkAllocate(op, result); @@ -268,6 +267,10 @@ static LogicalResult checkImplementationStatus(Operation &op) { checkDepend(op, result); checkNowait(op, result); }) + .Case([&](omp::TaskloopOp op) { + // TODO: Add other clauses check + checkUntied(op, result); + }) .Case([&](omp::WsloopOp op) { checkAllocate(op, result); checkLinear(op, result); diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir index 5f8bdf8afdf783e..8903bf283b5c750 100644 --- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir +++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir @@ -3020,6 +3020,18 @@ module attributes {omp.is_target_device = true} { // ----- +llvm.func @omp_task_untied() { + // The third argument is 0: which signifies the united task + // CHECK: {{.*}} = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 %{{.*}}, i32 0, + // CHECK-SAME: i64 40, i64 0, ptr @{{.*}}) + omp.task untied { + omp.terminator + } + llvm.return +} + +// ----- + // Third argument is 5: essentially (4 || 1) // signifying this task is TIED and MERGEABLE diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir index 8f3e466cfbbeb66..8ae795ec1ec6b05 100644 --- a/mlir/test/Target/LLVMIR/openmp-todo.mlir +++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir @@ -440,17 +440,6 @@ llvm.func @task_priority(%x : i32) { // ----- -llvm.func @task_untied() { - // expected-error@below {{not yet implemented: Unhandled clause untied in omp.task operation}} - // expected-error@below {{LLVM Translation failed for operation: omp.task}} - omp.task untied { - omp.terminator - } - llvm.return -} - -// ----- - llvm.func @taskgroup_allocate(%x : !llvm.ptr) { // expected-error@below {{not yet implemented: Unhandled clause allocate in omp.taskgroup operation}} // expected-error@below {{LLVM Translation failed for operation: omp.taskgroup}} @@ -503,6 +492,19 @@ llvm.func @taskloop(%lb : i32, %ub : i32, %step : i32) { // ----- +llvm.func @taskloop_untied(%lb : i32, %ub : i32, %step : i32) { + // expected-error@below {{not yet implemented: omp.taskloop}} + // expected-error@below {{LLVM Translation failed for operation: omp.taskloop}} + omp.taskloop untied { + omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) { + omp.yield + } + } + llvm.return +} + +// ----- + llvm.func @taskwait_depend(%x: !llvm.ptr) { // expected-error@below {{not yet implemented: Unhandled clause depend in omp.taskwait operation}} // expected-error@below {{LLVM Translation failed for operation: omp.taskwait}}