Skip to content

Commit c2aa11d

Browse files
[Flang] Add LLVM lowering support for UNTIED clause in Task (#121052)
Implementation details: The UNTIED clause is recognized by setting the flag=0 for the default case or performing logical OR to flag if other clauses are specified, and this flag is passed as an argument to the `__kmpc_omp_task_alloc` runtime call. Resubmitting the PR with fix for the failure, as it was reverted here: 927a70d and previously merged here: #115283
1 parent 9d9c561 commit c2aa11d

File tree

8 files changed

+106
-25
lines changed

8 files changed

+106
-25
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3341,6 +3341,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
33413341
!std::holds_alternative<clause::UseDevicePtr>(clause.u) &&
33423342
!std::holds_alternative<clause::InReduction>(clause.u) &&
33433343
!std::holds_alternative<clause::Mergeable>(clause.u) &&
3344+
!std::holds_alternative<clause::Untied>(clause.u) &&
33443345
!std::holds_alternative<clause::TaskReduction>(clause.u) &&
33453346
!std::holds_alternative<clause::Detach>(clause.u)) {
33463347
std::string name =

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,30 @@ class AssociatedLoopChecker {
213213
std::map<std::string, std::int64_t> constructNamesAndLevels_;
214214
};
215215

216+
// `OmpUnitedTaskDesignatorChecker` is used to check if the designator
217+
// can appear within the TASK construct
218+
class OmpUnitedTaskDesignatorChecker {
219+
public:
220+
OmpUnitedTaskDesignatorChecker(SemanticsContext &context)
221+
: context_{context} {}
222+
223+
template <typename T> bool Pre(const T &) { return true; }
224+
template <typename T> void Post(const T &) {}
225+
226+
bool Pre(const parser::Name &name) {
227+
if (name.symbol->test(Symbol::Flag::OmpThreadprivate)) {
228+
// OpenMP 5.2: 5.2 threadprivate directive restriction
229+
context_.Say(name.source,
230+
"A THREADPRIVATE variable `%s` cannot appear in an UNTIED TASK region"_err_en_US,
231+
name.source);
232+
}
233+
return true;
234+
}
235+
236+
private:
237+
SemanticsContext &context_;
238+
};
239+
216240
bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
217241
unsigned version{context_.langOptions().OpenMPVersion};
218242
DirectiveContext &dirCtx = GetContext();
@@ -1172,6 +1196,16 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
11721196
HasInvalidWorksharingNesting(
11731197
beginDir.source, llvm::omp::nestedWorkshareErrSet);
11741198
break;
1199+
case llvm::omp::Directive::OMPD_task: {
1200+
const auto &clauses{std::get<parser::OmpClauseList>(beginBlockDir.t)};
1201+
for (const auto &clause : clauses.v) {
1202+
if (std::get_if<parser::OmpClause::Untied>(&clause.u)) {
1203+
OmpUnitedTaskDesignatorChecker check{context_};
1204+
parser::Walk(block, check);
1205+
}
1206+
}
1207+
break;
1208+
}
11751209
default:
11761210
break;
11771211
}

flang/test/Lower/OpenMP/Todo/task_untied.f90

Lines changed: 0 additions & 13 deletions
This file was deleted.

flang/test/Lower/OpenMP/task.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,27 @@ subroutine task_multiple_clauses()
247247
!$omp end task
248248
end subroutine task_multiple_clauses
249249

250+
!===============================================================================
251+
! `mergeable` clause
252+
!===============================================================================
253+
250254
subroutine task_mergeable()
251255
!CHECK: omp.task mergeable {
252256
!CHECK: omp.terminator
253257
!CHECK: }
254258
!$omp task mergeable
255259
!$omp end task
256260
end subroutine
261+
262+
!===============================================================================
263+
! `untied` clause
264+
!===============================================================================
265+
266+
!CHECK-LABEL: func.func @_QPomp_task_untied() {
267+
subroutine omp_task_untied()
268+
!CHECK: omp.task untied {
269+
!$omp task untied
270+
call foo()
271+
!CHECK: omp.terminator
272+
!$omp end task
273+
end subroutine omp_task_untied
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenmp
2+
!
3+
! OpenMP 5.2: 5.2 threadprivate directive restriction
4+
5+
subroutine task_untied01()
6+
integer, save :: var_01, var_02(2)
7+
real :: var_03
8+
common /c/ var_03
9+
10+
!$omp threadprivate(var_01, var_02)
11+
!$omp threadprivate(/c/)
12+
13+
!$omp task untied
14+
!ERROR: A THREADPRIVATE variable `var_01` cannot appear in an UNTIED TASK region
15+
var_01 = 10
16+
!ERROR: A THREADPRIVATE variable `var_02` cannot appear in an UNTIED TASK region
17+
!ERROR: A THREADPRIVATE variable `var_01` cannot appear in an UNTIED TASK region
18+
var_02(1) = sum([var_01, 20])
19+
!$omp end task
20+
21+
!$omp task untied
22+
!ERROR: A THREADPRIVATE variable `var_02` cannot appear in an UNTIED TASK region
23+
!ERROR: A THREADPRIVATE variable `var_02` cannot appear in an UNTIED TASK region
24+
var_02(2) = product(var_02)
25+
!ERROR: A THREADPRIVATE variable `var_03` cannot appear in an UNTIED TASK region
26+
var_03 = 3.14
27+
!$omp end task
28+
end subroutine task_untied01

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
270270
.Case([&](omp::TaskOp op) {
271271
checkAllocate(op, result);
272272
checkInReduction(op, result);
273-
checkUntied(op, result);
274273
})
275274
.Case([&](omp::TaskgroupOp op) {
276275
checkAllocate(op, result);
@@ -282,6 +281,7 @@ static LogicalResult checkImplementationStatus(Operation &op) {
282281
})
283282
.Case([&](omp::TaskloopOp op) {
284283
// TODO: Add other clauses check
284+
checkUntied(op, result);
285285
checkPriority(op, result);
286286
})
287287
.Case([&](omp::WsloopOp op) {

mlir/test/Target/LLVMIR/openmp-llvm.mlir

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3171,6 +3171,18 @@ module attributes {omp.is_target_device = true} {
31713171

31723172
// -----
31733173

3174+
llvm.func @omp_task_untied() {
3175+
// The third argument is 0: which signifies the untied task
3176+
// CHECK: {{.*}} = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 %{{.*}}, i32 0,
3177+
// CHECK-SAME: i64 40, i64 0, ptr @{{.*}})
3178+
omp.task untied {
3179+
omp.terminator
3180+
}
3181+
llvm.return
3182+
}
3183+
3184+
// -----
3185+
31743186
// Third argument is 5: essentially (4 || 1)
31753187
// signifying this task is TIED and MERGEABLE
31763188

mlir/test/Target/LLVMIR/openmp-todo.mlir

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -400,17 +400,6 @@ llvm.func @task_in_reduction(%x : !llvm.ptr) {
400400

401401
// -----
402402

403-
llvm.func @task_untied() {
404-
// expected-error@below {{not yet implemented: Unhandled clause untied in omp.task operation}}
405-
// expected-error@below {{LLVM Translation failed for operation: omp.task}}
406-
omp.task untied {
407-
omp.terminator
408-
}
409-
llvm.return
410-
}
411-
412-
// -----
413-
414403
llvm.func @taskgroup_allocate(%x : !llvm.ptr) {
415404
// expected-error@below {{not yet implemented: Unhandled clause allocate in omp.taskgroup operation}}
416405
// expected-error@below {{LLVM Translation failed for operation: omp.taskgroup}}
@@ -463,6 +452,19 @@ llvm.func @taskloop(%lb : i32, %ub : i32, %step : i32) {
463452

464453
// -----
465454

455+
llvm.func @taskloop_untied(%lb : i32, %ub : i32, %step : i32) {
456+
// expected-error@below {{not yet implemented: omp.taskloop}}
457+
// expected-error@below {{LLVM Translation failed for operation: omp.taskloop}}
458+
omp.taskloop untied {
459+
omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
460+
omp.yield
461+
}
462+
}
463+
llvm.return
464+
}
465+
466+
// -----
467+
466468
llvm.func @taskwait_depend(%x: !llvm.ptr) {
467469
// expected-error@below {{not yet implemented: Unhandled clause depend in omp.taskwait operation}}
468470
// expected-error@below {{LLVM Translation failed for operation: omp.taskwait}}

0 commit comments

Comments
 (0)