398 lines · plain
1! This test checks lowering of OpenMP loop Directive.2 3! REQUIRES: openmp_runtime4 5! RUN: %flang_fc1 -emit-hlfir %openmp_flags -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s6 7! CHECK: omp.declare_reduction @[[RED:add_reduction_i32]] : i328! CHECK: omp.private {type = private} @[[DUMMY_PRIV:.*test_privateEdummy_private.*]] : i329! CHECK: omp.private {type = private} @[[I_PRIV:.*test_no_clausesEi.*]] : i3210 11! CHECK-LABEL: func.func @_QPtest_no_clauses12subroutine test_no_clauses()13 integer :: i, j, dummy = 114 15 ! CHECK: omp.simd private(@[[I_PRIV]] %{{.*}}#0 -> %[[ARG:.*]] : !fir.ref<i32>) {16 ! CHECK-NEXT: omp.loop_nest (%[[IV:.*]]) : i32 = (%{{.*}}) to (%{{.*}}) {{.*}} {17 ! CHECK: %[[ARG_DECL:.*]]:2 = hlfir.declare %[[ARG]]18 ! CHECK: hlfir.assign %[[IV]] to %[[ARG_DECL]]#0 : i32, !fir.ref<i32>19 ! CHECK: }20 ! CHECK: }21 !$omp loop22 do i=1,1023 dummy = dummy + 124 end do25 !$omp end loop26end subroutine27 28! CHECK-LABEL: func.func @_QPtest_collapse29subroutine test_collapse()30 integer :: i, j, dummy = 131 ! CHECK: omp.simd private(@{{.*}} %{{.*}}#0 -> %{{.*}}, @{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {32 ! CHECK-NEXT: omp.loop_nest (%{{.*}}, %{{.*}}) : i32 {{.*}} {33 ! CHECK: }34 ! CHECK: }35 !$omp loop collapse(2)36 do i=1,1037 do j=2,2038 dummy = dummy + 139 end do40 end do41 !$omp end loop42end subroutine43 44! CHECK-LABEL: func.func @_QPtest_private45subroutine test_private()46 integer :: i, dummy = 147 ! CHECK: omp.simd private(@[[DUMMY_PRIV]] %{{.*}}#0 -> %[[DUMMY_ARG:.*]], @{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {48 ! CHECK-NEXT: omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) {{.*}} {49 ! CHECK: %[[DUMMY_DECL:.*]]:2 = hlfir.declare %[[DUMMY_ARG]] {uniq_name = "_QFtest_privateEdummy"}50 ! CHECK: %{{.*}} = fir.load %[[DUMMY_DECL]]#051 ! CHECK: hlfir.assign %{{.*}} to %[[DUMMY_DECL]]#052 ! CHECK: }53 ! CHECK: }54 !$omp loop private(dummy)55 do i=1,1056 dummy = dummy + 157 end do58 !$omp end loop59end subroutine60 61 62! CHECK-LABEL: func.func @_QPtest_order63subroutine test_order()64 integer :: i, dummy = 165 ! CHECK: omp.loop order(reproducible:concurrent) private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {66 ! CHECK: }67 !$omp loop order(concurrent)68 do i=1,1069 dummy = dummy + 170 end do71 !$omp end loop72end subroutine73 74! CHECK-LABEL: func.func @_QPtest_reduction75subroutine test_reduction()76 integer :: i, dummy = 177 78 ! CHECK: omp.simd private(@{{.*}} %{{.*}}#0 -> %{{.*}} : !{{.*}}) reduction79 ! CHECK-SAME: (@[[RED]] %{{.*}}#0 -> %[[DUMMY_ARG:.*]] : !{{.*}}) {80 ! CHECK-NEXT: omp.loop_nest (%{{.*}}) : i32 = (%{{.*}}) to (%{{.*}}) {{.*}} {81 ! CHECK: %[[DUMMY_DECL:.*]]:2 = hlfir.declare %[[DUMMY_ARG]] {uniq_name = "_QFtest_reductionEdummy"}82 ! CHECK: %{{.*}} = fir.load %[[DUMMY_DECL]]#083 ! CHECK: hlfir.assign %{{.*}} to %[[DUMMY_DECL]]#084 ! CHECK: }85 ! CHECK: }86 !$omp loop reduction(+:dummy)87 do i=1,1088 dummy = dummy + 189 end do90 !$omp end loop91end subroutine92 93! CHECK-LABEL: func.func @_QPtest_bind94subroutine test_bind()95 integer :: i, dummy = 196 ! CHECK: omp.simd private(@{{.*}} %{{.*}}#0 -> %{{.*}} : {{.*}}) {97 ! CHECK: }98 !$omp loop bind(thread)99 do i=1,10100 dummy = dummy + 1101 end do102 !$omp end loop103end subroutine104 105! CHECK-LABEL: func.func @_QPtest_nested_directives106subroutine test_nested_directives107 implicit none108 integer, parameter :: N = 100000109 integer a(N), b(N), c(N)110 integer j,i, num, flag;111 num = N112 113 ! CHECK: omp.teams {114 115 ! Verify the first `loop` directive was combined with `target teams` into 116 ! `target teams distribute parallel do`.117 ! CHECK: omp.parallel {{.*}} {118 ! CHECK: omp.distribute {119 ! CHECK: omp.wsloop {120 ! CHECK: omp.loop_nest {{.*}} {121 122 ! Very the second `loop` directive was rewritten to `simd`.123 ! CHECK: omp.simd {{.*}} {124 ! CHECK: omp.loop_nest {{.*}} {125 ! CHECK: }126 ! CHECK: }127 128 ! CHECK: }129 ! CHECK: } {omp.composite}130 ! CHECK: } {omp.composite}131 ! CHECK: } {omp.composite}132 ! CHECK: }133 !$omp target teams map(to: a,b) map(from: c)134 !$omp loop135 do j=1,1000136 !$omp loop137 do i=1,N138 c(i) = a(i) * b(i)139 end do140 end do141 !$omp end target teams142end subroutine143 144! CHECK-LABEL: func.func @_QPtest_standalone_bind_teams145subroutine test_standalone_bind_teams146 implicit none147 integer, parameter :: N = 100000148 integer a(N), b(N), c(N)149 integer j,i, num, flag;150 num = N151 152 ! CHECK: omp.distribute153 ! CHECK-SAME: private(@{{.*}}Ea_private_box_100000xi32 {{[^,]*}},154 ! CHECK-SAME: @{{.*}}Ei_private_i32 {{.*}} : {{.*}}) {155 ! CHECK: omp.loop_nest {{.*}} {156 ! CHECK: }157 ! CHECK: }158 !$omp loop bind(teams) private(a)159 do i=1,N160 c(i) = a(i) * b(i)161 end do162end subroutine163 164! CHECK-LABEL: func.func @_QPtest_standalone_bind_parallel165subroutine test_standalone_bind_parallel166 implicit none167 integer, parameter :: N = 100000168 integer a(N), b(N), c(N)169 integer j,i, num, flag;170 num = N171 172 ! CHECK: omp.wsloop173 ! CHECK-SAME: private(@{{.*}}Ea_private_box_100000xi32 {{[^,]*}},174 ! CHECK-SAME: @{{.*}}Ei_private_i32 {{.*}} : {{.*}}) {175 ! CHECK: omp.loop_nest {{.*}} {176 ! CHECK: }177 ! CHECK: }178 !$omp loop bind(parallel) private(a)179 do i=1,N180 c(i) = a(i) * b(i)181 end do182end subroutine183 184! CHECK-LABEL: func.func @_QPteams_loop_cannot_be_parallel_for185subroutine teams_loop_cannot_be_parallel_for186 implicit none187 integer :: iter, iter2, val(20)188 val = 0189 ! CHECK: omp.teams {190 191 ! Verify the outer `loop` directive was mapped to only `distribute`.192 ! CHECK-NOT: omp.parallel {{.*}}193 ! CHECK: omp.distribute {{.*}} {194 ! CHECK-NEXT: omp.loop_nest {{.*}} {195 196 ! Verify the inner `loop` directive was mapped to a worksharing loop.197 ! CHECK: omp.wsloop {{.*}} {198 ! CHECK-NEXT: omp.loop_nest {{.*}} {199 ! CHECK: }200 ! CHECK: }201 202 ! CHECK: }203 ! CHECK: }204 205 ! CHECK: }206 !$omp target teams loop map(tofrom:val)207 DO iter = 1, 5208 !$omp loop bind(parallel)209 DO iter2 = 1, 5210 val(iter+iter2) = iter+iter2211 END DO212 END DO213end subroutine214 215subroutine foo()216end subroutine217 218! CHECK-LABEL: func.func @_QPteams_loop_cannot_be_parallel_for_2219subroutine teams_loop_cannot_be_parallel_for_2220 implicit none221 integer :: iter, val(20)222 val = 0223 224 ! CHECK: omp.teams {225 226 ! Verify the `loop` directive was mapped to only `distribute`.227 ! CHECK-NOT: omp.parallel {{.*}}228 ! CHECK: omp.distribute {{.*}} {229 ! CHECK-NEXT: omp.loop_nest {{.*}} {230 ! CHECK: fir.call @_QPfoo231 ! CHECK: }232 ! CHECK: }233 234 ! CHECK: }235 !$omp target teams loop map(tofrom:val)236 DO iter = 1, 5237 call foo()238 END DO239end subroutine240 241! CHECK-LABEL: func.func @_QPteams_loop_can_be_parallel_for242subroutine teams_loop_can_be_parallel_for243 use omp_lib244 implicit none245 integer :: iter, tid, val(20)246 val = 0247 248 !CHECK: omp.teams {249 !CHECK: omp.parallel {{.*}} {250 !CHECK: omp.distribute {251 !CHECK: omp.wsloop {252 !CHECK: omp.loop_nest {{.*}} {253 !CHECK: fir.call @omp_get_thread_num()254 !CHECK: }255 !CHECK: }256 !CHECK: }257 !CHECK: }258 !CHECK: }259 !$omp target teams loop map(tofrom:val)260 DO iter = 1, 5261 tid = omp_get_thread_num()262 END DO263end subroutine264 265! CHECK-LABEL: func.func @_QPteams_loop_cannot_be_parallel_for_4266subroutine teams_loop_cannot_be_parallel_for_4267 implicit none268 integer :: iter, iter2, tid, val(20)269 270 ! CHECK: omp.teams {271 272 ! Verify the outer `loop` directive was mapped to only `distribute`.273 ! CHECK-NOT: omp.parallel {{.*}}274 ! CHECK: omp.distribute {{.*}} {275 ! CHECK-NEXT: omp.loop_nest {{.*}} {276 277 ! Verify the inner `loop` directive was mapped to a worksharing loop.278 ! CHECK: omp.wsloop {{.*}} {279 ! CHECK: omp.loop_nest {{.*}} {280 ! CHECK: }281 ! CHECK: }282 283 ! CHECK: }284 ! CHECK: }285 286 ! CHECK: }287 !$omp target teams loop map(tofrom:val)288 DO iter = 1, 5289 !$omp parallel290 !$omp loop291 DO iter2 = 1, 5292 val(iter+iter2) = iter+iter2293 END DO294 !$omp end parallel295 END DO296end subroutine297 298! CHECK-LABEL: func.func @_QPloop_parallel_bind_reduction299subroutine loop_parallel_bind_reduction300 implicit none301 integer :: x, i302 303 ! CHECK: omp.wsloop304 ! CHECK-SAME: private(@{{[^[:space:]]+}} %{{[^[:space:]]+}}#0 -> %[[PRIV_ARG:[^[:space:]]+]] : !fir.ref<i32>)305 ! CHECK-SAME: reduction(@add_reduction_i32 %{{.*}}#0 -> %[[RED_ARG:.*]] : !fir.ref<i32>) {306 ! CHECK-NEXT: omp.loop_nest {{.*}} {307 ! CHECK-NEXT: hlfir.declare %[[PRIV_ARG]] {uniq_name = "_QF{{.*}}Ei"}308 ! CHECK-NEXT: hlfir.declare %[[RED_ARG]] {uniq_name = "_QF{{.*}}Ex"}309 ! CHECK: }310 ! CHECK: }311 !$omp loop bind(parallel) reduction(+: x)312 do i = 0, 10313 x = x + i314 end do315end subroutine316 317! CHECK-LABEL: func.func @_QPloop_teams_loop_reduction318subroutine loop_teams_loop_reduction319 implicit none320 integer :: x, i321 ! CHECK: omp.teams reduction(@add_reduction_i32 %{{.*}}#0 -> %[[TEAMS_RED_ARG:.*]] : !fir.ref<i32>) {322 ! CHECK: omp.parallel323 ! CHECK-SAME: private(@{{[^[:space:]]+}} %{{[^[:space:]]+}}#0 -> %[[PRIV_ARG:[^[:space:]]+]] : !fir.ref<i32>) {324 ! CHECK: omp.distribute {325 ! CHECK: omp.wsloop326 ! CHECK-SAME: reduction(@add_reduction_i32 %[[TEAMS_RED_ARG]] -> %[[RED_ARG:.*]] : !fir.ref<i32>) {327 ! CHECK-NEXT: omp.loop_nest {{.*}} {328 ! CHECK-NEXT: hlfir.declare %[[PRIV_ARG]] {uniq_name = "_QF{{.*}}Ei"}329 ! CHECK-NEXT: hlfir.declare %[[RED_ARG]] {uniq_name = "_QF{{.*}}Ex"}330 ! CHECK: }331 ! CHECK: }332 ! CHECK: }333 ! CHECK: }334 ! CHECK: }335 !$omp teams loop reduction(+: x)336 do i = 0, 10337 x = x + i338 end do339end subroutine340 341 342! Tests a regression when the pass encounters a multi-block `teams` region.343subroutine multi_block_teams344 implicit none345 integer :: i346 347 ! CHECK: omp.target {{.*}} {348 ! CHECK: omp.teams {349 ! CHECK: ^bb1:350 ! CHECK: cf.br ^bb2351 ! CHECK: ^bb2:352 ! CHECK: omp.terminator353 ! CHECK: }354 ! CHECK: }355 !$omp target teams356 select case (i)357 case(1)358 end select359 !$omp end target teams360end subroutine361 362 363! Verifies that reductions are hoisted to the parent `teams` directive and removed364! from the `loop` directive when `loop` is mapped to `distribute`.365 366! CHECK-LABEL: func.func @_QPteams_loop_cannot_be_parallel_for_with_reductions367subroutine teams_loop_cannot_be_parallel_for_with_reductions368 implicit none369 integer :: x, y, i, p370 371 ! CHECK: %[[ADD_RED:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QF{{.*}}Ex"}372 ! CHECK: %[[MUL_RED:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QF{{.*}}Ey"}373 ! CHECK: omp.teams reduction(374 ! CHECK-SAME: @add_reduction_i32 %[[ADD_RED]]#0 -> %[[ADD_RED_ARG:[^[:space:]]*]], 375 ! CHECK-SAME: @multiply_reduction_i32 %[[MUL_RED]]#0 -> %[[MUL_RED_ARG:.*]] : {{.*}}) {376 377 ! CHECK: omp.distribute private(@{{.*}} %{{.*}} -> %{{.*}}, @{{.*}} %{{.*}} -> %{{.*}} : {{.*}}) {378 ! CHECK: %[[ADD_RED_DECL:.*]]:2 = hlfir.declare %[[ADD_RED_ARG]] {uniq_name = "_QF{{.*}}Ex"}379 ! CHECK: %[[MUL_RED_DECL:.*]]:2 = hlfir.declare %[[MUL_RED_ARG]] {uniq_name = "_QF{{.*}}Ey"}380 381 ! CHECK: %[[ADD_RES:.*]] = arith.addi %{{.*}}, %{{.*}} : i32382 ! CHECK: hlfir.assign %[[ADD_RES]] to %[[ADD_RED_DECL]]#0 : i32, !fir.ref<i32>383 384 ! CHECK: %[[MUL_RES:.*]] = arith.muli %{{.*}}, %{{.*}} : i32385 ! CHECK: hlfir.assign %[[MUL_RES]] to %[[MUL_RED_DECL]]#0 : i32, !fir.ref<i32>386 ! CHECK: omp.yield387 ! CHECK: }388 ! CHECK: omp.terminator389 ! CHECK: }390 !$omp teams loop reduction(+: x) reduction(*: y) private(p)391 do i = 1, 5392 call foo()393 x = x + i394 y = y * i395 p = 42396 end do397end subroutine398