diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 71067283d13f7..22fdaf010755f 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -1770,14 +1770,18 @@ static void genTaskloopClauses(lower::AbstractConverter &converter, mlir::omp::TaskloopOperands &clauseOps) { ClauseProcessor cp(converter, semaCtx, clauses); + cp.processAllocate(clauseOps); + cp.processFinal(stmtCtx, clauseOps); cp.processGrainsize(stmtCtx, clauseOps); + cp.processIf(llvm::omp::Directive::OMPD_taskloop, clauseOps); + cp.processMergeable(clauseOps); cp.processNumTasks(stmtCtx, clauseOps); + cp.processPriority(stmtCtx, clauseOps); + cp.processUntied(clauseOps); - cp.processTODO(loc, llvm::omp::Directive::OMPD_taskloop); + cp.processTODO( + loc, llvm::omp::Directive::OMPD_taskloop); } static void genTaskwaitClauses(lower::AbstractConverter &converter, diff --git a/flang/test/Lower/OpenMP/Todo/taskloop-collapse.f90 b/flang/test/Lower/OpenMP/Todo/taskloop-collapse.f90 new file mode 100644 index 0000000000000..cd54f5eeba6c4 --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/taskloop-collapse.f90 @@ -0,0 +1,15 @@ +! 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 + +! CHECK: not yet implemented: Unhandled clause COLLAPSE in TASKLOOP construct +subroutine omp_taskloop_collapse() + integer x + x = 0 + !$omp taskloop collapse(2) + do i = 1, 100 + do j = 1, 100 + x = x + 1 + end do + end do + !$omp end taskloop +end subroutine omp_taskloop_collapse diff --git a/flang/test/Lower/OpenMP/Todo/taskloop-lastprivate.f90 b/flang/test/Lower/OpenMP/Todo/taskloop-lastprivate.f90 new file mode 100644 index 0000000000000..54f2580daf283 --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/taskloop-lastprivate.f90 @@ -0,0 +1,13 @@ +! 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 + +! CHECK: not yet implemented: Unhandled clause LASTPRIVATE in TASKLOOP construct +subroutine omp_taskloop_lastprivate() + integer x + x = 0 + !$omp taskloop lastprivate(x) + do i = 1, 100 + x = x + 1 + end do + !$omp end taskloop +end subroutine omp_taskloop_lastprivate diff --git a/flang/test/Lower/OpenMP/Todo/taskloop-nogroup.f90 b/flang/test/Lower/OpenMP/Todo/taskloop-nogroup.f90 new file mode 100644 index 0000000000000..2a0c5985290e2 --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/taskloop-nogroup.f90 @@ -0,0 +1,13 @@ +! 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 + +! CHECK: not yet implemented: Unhandled clause NOGROUP in TASKLOOP construct +subroutine omp_taskloop_nogroup() + integer x + x = 0 + !$omp taskloop nogroup + do i = 1, 100 + x = x + 1 + end do + !$omp end taskloop +end subroutine omp_taskloop_nogroup diff --git a/flang/test/Lower/OpenMP/if-clause.f90 b/flang/test/Lower/OpenMP/if-clause.f90 index 3ae9018ae4d5d..e8f69b470e2ca 100644 --- a/flang/test/Lower/OpenMP/if-clause.f90 +++ b/flang/test/Lower/OpenMP/if-clause.f90 @@ -12,7 +12,6 @@ program main ! - PARALLEL SECTIONS ! - PARALLEL WORKSHARE ! - TARGET UPDATE - ! - TASKLOOP ! - TASKLOOP SIMD ! ---------------------------------------------------------------------------- @@ -1580,4 +1579,29 @@ program main !$omp teams if(teams: .true.) i = 1 !$omp end teams + + ! ---------------------------------------------------------------------------- + ! TASKLOOP + ! ---------------------------------------------------------------------------- + + ! CHECK: omp.taskloop + ! CHECK-NOT: if({{.*}}) + !$omp taskloop + do i = 1, 10 + end do + !$omp end taskloop + + ! CHECK: omp.taskloop + ! CHECK-SAME: if({{.*}}) + !$omp taskloop if(.true.) + do i = 1, 10 + end do + !$omp end taskloop + + ! CHECK: omp.taskloop + ! CHECK-SAME: if({{.*}}) + !$omp taskloop if(taskloop: .true.) + do i = 1, 10 + end do + !$omp end taskloop end program main diff --git a/flang/test/Lower/OpenMP/implicit-dsa.f90 b/flang/test/Lower/OpenMP/implicit-dsa.f90 index 0d2db63edfe79..9d01460253899 100644 --- a/flang/test/Lower/OpenMP/implicit-dsa.f90 +++ b/flang/test/Lower/OpenMP/implicit-dsa.f90 @@ -5,6 +5,36 @@ ! Privatizers +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[TASKLOOP_TEST3_I_PRIVATE:.*]] : i32 +! CHECK-NOT: copy { + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = firstprivate} @[[TASKLOOP_TEST3_X_FIRSTPRIVATE:.*]] : i32 +! CHECK-SAME: copy { +! CHECK: hlfir.assign + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[TASKLOOP_TEST2_X_PRIVATE:.*]] : i32 +! CHECK-NOT: copy { + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[TASKLOOP_TEST2_I_PRIVATE:.*]] : i32 +! CHECK-NOT: copy { + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[TASKLOOP_TEST1_I_PRIVATE:.*]] : i32 +! CHECK-NOT: copy { + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = firstprivate} @[[TASKLOOP_TEST1_X_FIRSTPRIVATE:.*]] : i32 +! CHECK-SAME: copy { +! CHECK: hlfir.assign + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[TASKLOOP_TEST1_Y_PRIVATE:.*]] : i32 +! CHECK-NOT: copy { + ! CHECK-LABEL: omp.private ! CHECK-SAME: {type = firstprivate} @[[TEST7_Y_FIRSTPRIV:.*]] : i32 ! CHECK-SAME: copy { @@ -310,4 +340,100 @@ subroutine implicit_dsa_test7 !$omp end task end subroutine -! TODO Test taskloop +! Test taskloop +! CHECK-LABEL: func.func @_QPimplicit_dsa_taskloop_test1 +! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFimplicit_dsa_taskloop_test1Ei"} +! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFimplicit_dsa_taskloop_test1Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFimplicit_dsa_taskloop_test1Ex"} +! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFimplicit_dsa_taskloop_test1Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[ALLOCA_Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFimplicit_dsa_taskloop_test1Ey"} +! CHECK: %[[DECL_Y:.*]]:2 = hlfir.declare %[[ALLOCA_Y]] {uniq_name = "_QFimplicit_dsa_taskloop_test1Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[ALLOCA_Z:.*]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFimplicit_dsa_taskloop_test1Ez"} +! CHECK: %[[DECL_Z:.*]]:2 = hlfir.declare %[[ALLOCA_Z]] {uniq_name = "_QFimplicit_dsa_taskloop_test1Ez"} : (!fir.ref) -> (!fir.ref, !fir.ref) +subroutine implicit_dsa_taskloop_test1 + integer :: x, y, z + ! CHECK: omp.taskloop private( + ! CHECK-SAME: @[[TASKLOOP_TEST1_Y_PRIVATE]] %[[DECL_Y]]#0 -> %[[ARG0:.*]], @[[TASKLOOP_TEST1_X_FIRSTPRIVATE]] %[[DECL_X]]#0 -> %[[ARG1:.*]], @[[TASKLOOP_TEST1_I_PRIVATE]] %[[DECL_I]]#0 -> %[[ARG2:.*]] : !fir.ref, !fir.ref, !fir.ref) { + ! CHECK: omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) inclusive step (%{{.*}}) { + !$omp taskloop private(y) shared(z) + do i = 1, 100 + ! CHECK: %[[Y_VAL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFimplicit_dsa_taskloop_test1Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) + ! CHECK: %[[X_VAL:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFimplicit_dsa_taskloop_test1Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) + ! CHECK: %[[LOAD_Z:.*]] = fir.load %[[DECL_Z]]#0 : !fir.ref + x = y + z + ! CHECK: hlfir.assign %{{.*}} to %[[X_VAL]]#0 : i32, !fir.ref + end do + !$omp end taskloop + + ! CHECK: omp.taskloop private(@[[TASKLOOP_TEST1_I_PRIVATE]] %[[DECL_I]]#0 -> %[[ARG0:.*]] : !fir.ref) { + !$omp taskloop default(shared) + do i = 1, 100 + ! CHECK: %[[LOAD_Y:.*]] = fir.load %[[DECL_Y]]#0 : !fir.ref + ! CHECK: %[[LOAD_Z:.*]] = fir.load %[[DECL_Z]]#0 : !fir.ref + ! CHECK: %[[ADD_VAL:.*]] = arith.addi %[[LOAD_Y]], %[[LOAD_Z]] : i32 + x = y + z + ! CHECK: hlfir.assign %[[ADD_VAL]] to %[[DECL_X]]#0 : i32, !fir.ref + end do + !$omp end taskloop +end subroutine + +! Nested taskloop with implicit shared DSA variables. +! CHECK-LABEL: func @_QPimplicit_dsa_taskloop_test2 +! CHECK: %[[I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFimplicit_dsa_taskloop_test2Ei"} +! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I]] {uniq_name = "_QFimplicit_dsa_taskloop_test2Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFimplicit_dsa_taskloop_test2Ex"} +! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFimplicit_dsa_taskloop_test2Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) +subroutine implicit_dsa_taskloop_test2 + integer :: x + ! CHECK: omp.parallel { + !$omp parallel + ! CHECK: omp.taskloop private(@[[TASKLOOP_TEST2_I_PRIVATE]] %[[I_DECL]]#0 -> %[[ARG0:.*]] : !fir.ref) { + !$omp taskloop + do i = 1, 100 + ! CHECK: hlfir.assign %{{.*}} to %[[X_DECL]]#0 : i32, !fir.ref + x = 2 + end do + !$omp end taskloop + + ! CHECK: omp.taskloop private(@[[TASKLOOP_TEST2_X_PRIVATE]] %[[X_DECL]]#0 -> %[[ARG0]], @[[TASKLOOP_TEST2_I_PRIVATE]] %[[I_DECL]]#0 -> %[[ARG1:.*]] : !fir.ref, !fir.ref) { + !$omp taskloop private(x) + do i = 1, 10 + ! CHECK: %[[DECL_PRIV_X:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFimplicit_dsa_taskloop_test2Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) + ! CHECK: %[[LOAD_X:.*]] = fir.load %[[DECL_PRIV_X]]#0 : !fir.ref + x = x + 1 + ! CHECK: hlfir.assign %{{.*}} to %[[DECL_PRIV_X]]#0 : i32, !fir.ref + end do + !$omp end parallel + +end subroutine + +! Taskloop with implicit firstprivate DSA variables, enclosed in private context. + +! CHECK-LABEL: func @_QPimplicit_dsa_taskloop_test3 +! CHECK: %[[I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFimplicit_dsa_taskloop_test3Ei"} +! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I]] {uniq_name = "_QFimplicit_dsa_taskloop_test3Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFimplicit_dsa_taskloop_test3Ex"} +! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFimplicit_dsa_taskloop_test3Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[Y:.*]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFimplicit_dsa_taskloop_test3Ey"} +! CHECK: %[[Y_DECL:.*]]:2 = hlfir.declare %[[Y]] {uniq_name = "_QFimplicit_dsa_taskloop_test3Ey"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[Z:.*]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFimplicit_dsa_taskloop_test3Ez"} +! CHECK: %[[Z_DECL:.*]]:2 = hlfir.declare %[[Z]] {uniq_name = "_QFimplicit_dsa_taskloop_test3Ez"} : (!fir.ref) -> (!fir.ref, !fir.ref) + +subroutine implicit_dsa_taskloop_test3 + integer :: x, y, z + ! CHECK: omp.parallel private(@[[TASKLOOP_TEST3_X_FIRSTPRIVATE]] %[[X_DECL]]#0 -> %[[ARG0:.*]] : !fir.ref) { + ! CHECK: %[[X_PRIV_VAL:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QFimplicit_dsa_taskloop_test3Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) + !$omp parallel firstprivate(x) + ! CHECK: omp.taskloop private(@[[TASKLOOP_TEST3_X_FIRSTPRIVATE]] %[[X_PRIV_VAL]]#0 -> %[[ARG1:.*]], @[[TASKLOOP_TEST3_I_PRIVATE]] %[[I_DECL]]#0 -> %[[ARG2:.*]] : !fir.ref, !fir.ref) { + !$omp taskloop + ! CHECK: %[[X_VAL:.*]]:2 = hlfir.declare %[[ARG1]] {uniq_name = "_QFimplicit_dsa_taskloop_test3Ex"} : (!fir.ref) -> (!fir.ref, !fir.ref) + do i = 1, 100 + ! CHECK: %[[LOAD_Y:.*]] = fir.load %[[Y_DECL]]#0 : !fir.ref + ! CHECK: %[[LOAD_Z:.*]] = fir.load %[[Z_DECL]]#0 : !fir.ref + x = y + z + ! CHECK: hlfir.assign %{{.*}} to %[[X_VAL]]#0 : i32, !fir.ref + end do + !$omp end taskloop + !$omp end parallel +end subroutine + diff --git a/flang/test/Lower/OpenMP/taskloop.f90 b/flang/test/Lower/OpenMP/taskloop.f90 index 79b0c20e176c0..4a06e4def0c83 100644 --- a/flang/test/Lower/OpenMP/taskloop.f90 +++ b/flang/test/Lower/OpenMP/taskloop.f90 @@ -1,5 +1,27 @@ -! RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s -! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s +! REQUIRES: openmp_runtime +! RUN: bbc -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir %openmp_flags -o - %s 2>&1 | FileCheck %s + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[OMP_TASKLOOP_UNTIEDEI_PRIVATE_I32:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[QFTEST_PRIORITYEI_PRIVATE_I32:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[QFTEST_MERGEABLEEI_PRIVATE_I32:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[I_PRIVATE_IF_TEST1:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[I_PRIVATE_FINAL:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[I_PRIVATE_TEST_ALLOCATE:.*]] : i32 + +! CHECK-LABEL: omp.private +! CHECK-SAME: {type = private} @[[X_PRIVATE_TEST_ALLOCATE:.*]] : i32 ! CHECK-LABEL: omp.private ! CHECK-SAME: {type = private} @[[I_PRIVATE_TEST2:.*]] : i32 @@ -70,3 +92,106 @@ subroutine omp_taskloop_private ! CHECK: } !$omp end taskloop end subroutine omp_taskloop_private + +!=============================================================================== +! `allocate` clause +!=============================================================================== + +! CHECK-LABEL: func.func @_QPtaskloop_allocate +! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtaskloop_allocateEi"} +! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFtaskloop_allocateEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[ALLOCA_X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtaskloop_allocateEx"} +! CHECK: %[[DECL_X:.*]]:2 = hlfir.declare %[[ALLOCA_X]] {uniq_name = "_QFtaskloop_allocateEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +subroutine taskloop_allocate() + use omp_lib + integer :: x + ! CHECK: omp.taskloop allocate(%{{.*}} : i64 -> %[[DECL_X]]#0 : !fir.ref) + ! CHECK-SAME: private(@[[X_PRIVATE_TEST_ALLOCATE]] %[[DECL_X]]#0 -> %[[ARG0:.*]], @[[I_PRIVATE_TEST_ALLOCATE]] %[[DECL_I]]#0 -> %[[ARG1:.*]] : !fir.ref, !fir.ref) { + !$omp taskloop allocate(omp_high_bw_mem_alloc: x) private(x) + do i = 1, 100 + ! CHECK: arith.addi + x = x + 12 + ! CHECK: omp.yield + end do + !$omp end taskloop +end subroutine taskloop_allocate + +!=============================================================================== +! `final` clause +!=============================================================================== + +! CHECK-LABEL: func.func @_QPtaskloop_final +! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtaskloop_finalEi"} +! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFtaskloop_finalEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +subroutine taskloop_final() + ! CHECK: omp.taskloop final(%true) private(@[[I_PRIVATE_FINAL]] %[[DECL_I]]#0 -> %[[ARG0:.*]] : !fir.ref) { + !$omp taskloop final(.true.) + do i = 1, 100 + ! CHECK: fir.call @_QPfoo() + call foo() + end do + !$omp end taskloop +end subroutine + +!=============================================================================== +! `if` clause +!=============================================================================== + +! CHECK-LABEL: func.func @_QPomp_taskloop_if +! CHECK: %[[DECL_BAR:.*]]:2 = hlfir.declare %[[ARG0:.*]] dummy_scope %{{.*}} +! CHECK: %[[ALLOCA_I:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFomp_taskloop_ifEi"} +! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[ALLOCA_I]] {uniq_name = "_QFomp_taskloop_ifEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[LOAD_VAL:.*]] = fir.load %[[DECL_BAR]]#0 : !fir.ref> +! CHECK: %[[VAL_BAR:.*]] = fir.convert %[[LOAD_VAL]] : (!fir.logical<4>) -> i1 +subroutine omp_taskloop_if(bar) + logical, intent(inout) :: bar + !CHECK: omp.taskloop if(%[[VAL_BAR]]) private(@[[I_PRIVATE_IF_TEST1]] %[[DECL_I]]#0 -> %[[ARG1:.*]] : !fir.ref) { + !$omp taskloop if(bar) + do i = 1, 10 + call foo() + end do + !$omp end taskloop +end subroutine omp_taskloop_if + +!=============================================================================== +! `mergeable` clause +!=============================================================================== + +! CHECK-LABEL: func.func @_QPtest_mergeable +subroutine test_mergeable + ! CHECK: omp.taskloop mergeable + !$omp taskloop mergeable + do i = 1, 10 + end do + !$omp end taskloop +end subroutine test_mergeable + +!=============================================================================== +! `priority` clause +!=============================================================================== + +! CHECK-LABEL: func.func @_QPtest_priority +! CHECK: %[[VAL1:.*]]:2 = hlfir.declare %[[ARG0:.*]] dummy_scope %{{.*}} +! CHECK: %[[LOAD_VAL:.*]] = fir.load %[[VAL1]]#0 : !fir.ref +subroutine test_priority(n) + integer, intent(inout) :: n + ! CHECK: omp.taskloop priority(%[[LOAD_VAL]] : i32) + !$omp taskloop priority(n) + do i = 1, 10 + end do + !$omp end taskloop +end subroutine test_priority + +!=============================================================================== +! `untied` clause +!=============================================================================== + +! CHECK-LABEL: func.func @_QPomp_taskloop_untied +subroutine omp_taskloop_untied() + ! CHECK: omp.taskloop untied + !$omp taskloop untied + do i = 1, 10 + call foo() + end do + !$omp end taskloop +end subroutine