1! REQUIRES: openmp_runtime 2 3!RUN: %flang_fc1 -emit-hlfir %openmp_flags %s -o - | FileCheck %s 4 5!CHECK-LABEL: func @_QPomp_task_simple() { 6subroutine omp_task_simple 7 !CHECK: omp.task { 8 !$omp task 9 !CHECK: fir.call @_QPfoo() {{.*}}: () -> () 10 call foo() 11 !CHECK: omp.terminator 12 !$omp end task 13end subroutine omp_task_simple 14 15!=============================================================================== 16! `if` clause 17!=============================================================================== 18 19!CHECK-LABEL: func @_QPomp_task_if(%{{.+}}) { 20subroutine omp_task_if(bar) 21 logical, intent(inout) :: bar 22 !CHECK: omp.task if(%{{.+}}) { 23 !$omp task if(bar) 24 !CHECK: fir.call @_QPfoo() {{.*}}: () -> () 25 call foo() 26 !CHECK: omp.terminator 27 !$omp end task 28end subroutine omp_task_if 29 30!=============================================================================== 31! `final` clause 32!=============================================================================== 33 34!CHECK-LABEL: func @_QPomp_task_final(%{{.+}}) { 35subroutine omp_task_final(bar) 36 logical, intent(inout) :: bar 37 !CHECK: omp.task final(%{{.+}}) { 38 !$omp task final(bar) 39 !CHECK: fir.call @_QPfoo() {{.*}}: () -> () 40 call foo() 41 !CHECK: omp.terminator 42 !$omp end task 43end subroutine omp_task_final 44 45!=============================================================================== 46! `priority` clause 47!=============================================================================== 48 49!CHECK-LABEL: func @_QPomp_task_priority(%{{.+}}) { 50subroutine omp_task_priority(bar) 51 integer, intent(inout) :: bar 52 !CHECK: omp.task priority(%{{.+}}) { 53 !$omp task priority(bar) 54 !CHECK: fir.call @_QPfoo() {{.*}}: () -> () 55 call foo() 56 !CHECK: omp.terminator 57 !$omp end task 58end subroutine omp_task_priority 59 60!=============================================================================== 61! `allocate` clause 62!=============================================================================== 63 64!CHECK-LABEL: func @_QPtask_allocate 65subroutine task_allocate() 66 use omp_lib 67 integer :: x 68 !CHECK: omp.task allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) { 69 !$omp task allocate(omp_high_bw_mem_alloc: x) private(x) 70 !CHECK: arith.addi 71 x = x + 12 72 !CHECK: omp.terminator 73 !$omp end task 74end subroutine task_allocate 75 76!=============================================================================== 77! `depend` clause 78!=============================================================================== 79 80!CHECK-LABEL: func @_QPtask_depend 81subroutine task_depend() 82 integer :: x 83 !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>) { 84 !$omp task depend(in : x) 85 !CHECK: arith.addi 86 x = x + 12 87 !CHECK: omp.terminator 88 !$omp end task 89end subroutine task_depend 90 91!CHECK-LABEL: func @_QPtask_depend_non_int 92subroutine task_depend_non_int() 93 character(len = 15) :: x 94 integer, allocatable :: y 95 complex :: z 96 !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<!fir.char<1,15>>, taskdependin -> %{{.+}} : !fir.ref<!fir.box<!fir.heap<i32>>>, taskdependin -> %{{.+}} : !fir.ref<complex<f32>>) { 97 !$omp task depend(in : x, y, z) 98 !CHECK: omp.terminator 99 !$omp end task 100end subroutine task_depend_non_int 101 102!CHECK-LABEL: func @_QPtask_depend_all_kinds_one_task 103subroutine task_depend_all_kinds_one_task() 104 integer :: x 105 !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>, taskdependout -> %{{.+}} : !fir.ref<i32>, taskdependinout -> %{{.+}} : !fir.ref<i32>) { 106 !$omp task depend(in : x) depend(out : x) depend(inout : x) 107 !CHECK: arith.addi 108 x = x + 12 109 !CHECK: omp.terminator 110 !$omp end task 111end subroutine task_depend_all_kinds_one_task 112 113!CHECK-LABEL: func @_QPtask_depend_multi_var 114subroutine task_depend_multi_var() 115 integer :: x 116 integer :: y 117 !CHECK: omp.task depend(taskdependin -> %{{.*}} : !fir.ref<i32>, taskdependin -> %{{.+}} : !fir.ref<i32>) private({{.*x_firstprivate.*}}, {{.*y_firstprivate.*}}) { 118 !$omp task depend(in :x,y) 119 !CHECK: arith.addi 120 x = x + 12 121 y = y + 12 122 !CHECK: omp.terminator 123 !$omp end task 124end subroutine task_depend_multi_var 125 126!CHECK-LABEL: func @_QPtask_depend_multi_task 127subroutine task_depend_multi_task() 128 integer :: x 129 !CHECK: omp.task depend(taskdependout -> %{{.+}} : !fir.ref<i32>) 130 !$omp task depend(out : x) 131 !CHECK: arith.addi 132 x = x + 12 133 !CHECK: omp.terminator 134 !$omp end task 135 !CHECK: omp.task depend(taskdependinout -> %{{.+}} : !fir.ref<i32>) 136 !$omp task depend(inout : x) 137 !CHECK: arith.addi 138 x = x + 12 139 !CHECK: omp.terminator 140 !$omp end task 141 !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref<i32>) 142 !$omp task depend(in : x) 143 !CHECK: arith.addi 144 x = x + 12 145 !CHECK: omp.terminator 146 !$omp end task 147 !CHECK: omp.task depend(taskdependmutexinoutset -> %{{.+}} : !fir.ref<i32>) 148 !$omp task depend(mutexinoutset : x) 149 !CHECK: arith.subi 150 x = x - 12 151 !CHECK: omp.terminator 152 !$omp end task 153 !CHECK: omp.task depend(taskdependinoutset -> %{{.+}} : !fir.ref<i32>) 154 !$omp task depend(inoutset : x) 155 !CHECK: arith.subi 156 x = x - 12 157 !CHECK: omp.terminator 158 !$omp end task 159end subroutine task_depend_multi_task 160 161!=============================================================================== 162! `private` clause 163!=============================================================================== 164!CHECK-LABEL: func @_QPtask_private 165subroutine task_private 166 type mytype 167 integer :: x 168 end type mytype 169 170!CHECK: %[[INT_ALLOCA:.*]] = fir.alloca i32 {bindc_name = "int_var", uniq_name = "_QFtask_privateEint_var"} 171!CHECK: %[[INT_VAR:.+]]:2 = hlfir.declare %[[INT_ALLOCA]] {uniq_name = "_QFtask_privateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 172!CHECK: %[[MYTYPE_ALLOCA:.*]] = fir.alloca !fir.type<_QFtask_privateTmytype{x:i32}> {bindc_name = "mytype_var", uniq_name = "_QFtask_privateEmytype_var"} 173!CHECK: %[[MYTYPE_VAR:.+]]:2 = hlfir.declare %[[MYTYPE_ALLOCA]] {uniq_name = "_QFtask_privateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) 174 integer :: int_var 175 type(mytype) :: mytype_var 176 177 !CHECK: fir.call @_QPbar(%[[INT_VAR]]#1, %[[MYTYPE_VAR]]#1) {{.*}}: (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> () 178 call bar(int_var, mytype_var) 179 180 !CHECK: omp.task private(@{{.*int_var_private.*}} %[[INT_VAR]]#0 -> %[[INT_VAR_ARG:.*]], @{{.*mytype_var_private.*}} %[[MYTYPE_VAR]]#0 -> %[[MYTYPE_VAR_ARG:.*]] : !fir.ref<i32>, !fir.ref<!fir.type<{{.*}}>) { 181 !$omp task private(int_var, mytype_var) 182!CHECK: %[[INT_VAR_PRIVATE:.+]]:2 = hlfir.declare %[[INT_VAR_ARG]] {uniq_name = "_QFtask_privateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 183!CHECK: %[[MYTYPE_VAR_PRIVATE:.+]]:2 = hlfir.declare %[[MYTYPE_VAR_ARG]] {uniq_name = "_QFtask_privateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) 184!CHECK: fir.call @_QPbar(%[[INT_VAR_PRIVATE]]#1, %[[MYTYPE_VAR_PRIVATE]]#1) fastmath<contract> : (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_privateTmytype{x:i32}>>) -> () 185 call bar(int_var, mytype_var) 186 !CHECK: omp.terminator 187 !$omp end task 188end subroutine task_private 189 190!=============================================================================== 191! `firstprivate` clause 192!=============================================================================== 193!CHECK-LABEL: func @_QPtask_firstprivate 194subroutine task_firstprivate 195 type mytype 196 integer :: x 197 end type mytype 198 199 !CHECK: %[[INT_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "int_var", uniq_name = "_QFtask_firstprivateEint_var"} 200 !CHECK: %[[INT_VAR:.+]]:2 = hlfir.declare %[[INT_ALLOCA]] {uniq_name = "_QFtask_firstprivateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 201 !CHECK: %[[MYTYPE_ALLOCA:.+]] = fir.alloca !fir.type<_QFtask_firstprivateTmytype{x:i32}> {bindc_name = "mytype_var", uniq_name = "_QFtask_firstprivateEmytype_var"} 202 !CHECK: %[[MYTYPE_VAR:.+]]:2 = hlfir.declare %[[MYTYPE_ALLOCA]] {uniq_name = "_QFtask_firstprivateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) 203 integer :: int_var 204 type(mytype) :: mytype_var 205 206!CHECK: fir.call @_QPbaz(%[[INT_VAR]]#1, %[[MYTYPE_VAR]]#1) fastmath<contract> : (!fir.ref<i32>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> () 207 call baz(int_var, mytype_var) 208 209 !CHECK: omp.task private(@{{.*int_var_firstprivate.*}} %[[INT_VAR]]#0 -> %[[INT_VAR_ARG:.*]], @{{.*mytype_var_firstprivate.*}} %[[MYTYPE_VAR]]#0 -> %[[MYTYPE_VAR_ARG:.*]] : !fir.ref<i32>, !fir.ref<{{.*}}) { 210 !$omp task firstprivate(int_var, mytype_var) 211!CHECK: %[[INT_VAR_FIRSTPRIVATE:.+]]:2 = hlfir.declare %[[INT_VAR_ARG]] {uniq_name = "_QFtask_firstprivateEint_var"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 212!CHECK: %[[MYTYPE_VAR_FIRSTPRIVATE:.+]]:2 = hlfir.declare %[[MYTYPE_VAR_ARG]] {uniq_name = "_QFtask_firstprivateEmytype_var"} : (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) -> (!fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>, !fir.ref<!fir.type<_QFtask_firstprivateTmytype{x:i32}>>) 213 call baz(int_var, mytype_var) 214 !CHECK: omp.terminator 215 !$omp end task 216end subroutine task_firstprivate 217 218!=============================================================================== 219! Multiple clauses 220!=============================================================================== 221 222!CHECK-LABEL: func @_QPtask_multiple_clauses 223subroutine task_multiple_clauses() 224 use omp_lib 225 226!CHECK: %[[X_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtask_multiple_clausesEx"} 227!CHECK: %[[X:.+]]:2 = hlfir.declare %[[X_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 228!CHECK: %[[Y_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFtask_multiple_clausesEy"} 229!CHECK: %[[Y:.+]]:2 = hlfir.declare %[[Y_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 230!CHECK: %[[Z_ALLOCA:.+]] = fir.alloca i32 {bindc_name = "z", uniq_name = "_QFtask_multiple_clausesEz"} 231!CHECK: %[[Z:.+]]:2 = hlfir.declare %[[Z_ALLOCA]] {uniq_name = "_QFtask_multiple_clausesEz"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 232 integer :: x, y, z 233 logical :: buzz 234 235 !CHECK: omp.task allocate(%{{.+}} : i64 -> %{{.+}} : !fir.ref<i32>) final(%{{.+}}) if(%{{.+}}) priority(%{{.+}}) private({{.*}}) { 236 !$omp task if(buzz) final(buzz) priority(z) allocate(omp_high_bw_mem_alloc: x) private(x) firstprivate(y) 237 238!CHECK: %[[X_PRIV:.+]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtask_multiple_clausesEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 239!CHECK: %[[Y_PRIV:.+]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtask_multiple_clausesEy"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) 240 241 !CHECK: arith.addi 242 x = x + 12 243 !CHECK: arith.subi 244 y = y - 12 245 246 !CHECK: omp.terminator 247 !$omp end task 248end subroutine task_multiple_clauses 249 250!=============================================================================== 251! `mergeable` clause 252!=============================================================================== 253 254subroutine task_mergeable() 255!CHECK: omp.task mergeable { 256!CHECK: omp.terminator 257!CHECK: } 258 !$omp task mergeable 259 !$omp end task 260end subroutine 261 262!=============================================================================== 263! `untied` clause 264!=============================================================================== 265 266!CHECK-LABEL: func.func @_QPomp_task_untied() { 267subroutine omp_task_untied() 268 !CHECK: omp.task untied { 269 !$omp task untied 270 call foo() 271 !CHECK: omp.terminator 272 !$omp end task 273end subroutine omp_task_untied 274