! This test checks lowering of OpenACC loop directive. ! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s ! CHECK-LABEL: acc.private.recipe @privatization_ref_10x10xf32 : !fir.ref> init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): ! CHECK: acc.yield %{{.*}} : !fir.ref> ! CHECK: } program acc_loop integer :: i, j, k integer, parameter :: n = 10 real, dimension(n) :: a, b real, dimension(n, n) :: c, d integer :: gangNum = 8 integer :: gangDim = 1 integer :: gangStatic = 8 integer :: vectorLength = 128 integer, parameter :: tileSize = 2 integer :: reduction_i real :: reduction_r !$acc loop DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]}{{$}} !$acc loop seq DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, seq = [#acc.device_type]} !$acc loop auto DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {auto_ = [#acc.device_type], inclusiveUpperbound = array} !$acc loop independent DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop gang DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop gang private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop gang(num: 8) DO i = 1, n a(i) = b(i) END DO ! CHECK: [[GANGNUM1:%.*]] = arith.constant 8 : i32 ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop gang({num=[[GANGNUM1]] : i32}) private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop gang(num: gangNum) DO i = 1, n a(i) = b(i) END DO ! CHECK: [[GANGNUM2:%.*]] = fir.load %{{.*}} : !fir.ref ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop gang({num=[[GANGNUM2]] : i32}) private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop gang(num: gangNum, static: gangStatic) DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop gang({num=%{{.*}} : i32, static=%{{.*}} : i32}) private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop vector DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop vector private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop vector(128) DO i = 1, n a(i) = b(i) END DO ! CHECK: [[CONSTANT128:%.*]] = arith.constant 128 : i32 ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop vector([[CONSTANT128]] : i32) private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop vector(vectorLength) DO i = 1, n a(i) = b(i) END DO ! CHECK: [[VECTORLENGTH:%.*]] = fir.load %{{.*}} : !fir.ref ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop vector([[VECTORLENGTH]] : i32) private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop worker DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop worker private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop worker(128) DO i = 1, n a(i) = b(i) END DO ! CHECK: [[WORKER128:%.*]] = arith.constant 128 : i32 ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop worker([[WORKER128]] : i32) private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop private(c) DO i = 1, n c(:,i) = d(:,i) END DO ! CHECK: %[[PRIVATE_C:.*]] = acc.private varPtr(%{{.*}} : !fir.ref>) recipe(@privatization_ref_10x10xf32) -> !fir.ref> {name = "c"} ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_C]], %[[PRIVATE_I]] : !fir.ref>, !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} ! When the induction variable is explicitly private - only a single private entry should be created. !$acc loop private(i) DO i = 1, n a(i) = b(i) END DO ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_I]] : !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop private(c, d) DO i = 1, n c(:,i) = d(:,i) END DO ! CHECK: %[[PRIVATE_C:.*]] = acc.private varPtr(%{{.*}} : !fir.ref>) recipe(@privatization_ref_10x10xf32) -> !fir.ref> {name = "c"} ! CHECK: %[[PRIVATE_D:.*]] = acc.private varPtr(%{{.*}} : !fir.ref>) recipe(@privatization_ref_10x10xf32) -> !fir.ref> {name = "d"} ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_C]], %[[PRIVATE_D]], %[[PRIVATE_I]] : !fir.ref>, !fir.ref>, !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop private(c) private(d) DO i = 1, n c(:,i) = d(:,i) END DO ! CHECK: %[[PRIVATE_C:.*]] = acc.private varPtr(%{{.*}} : !fir.ref>) recipe(@privatization_ref_10x10xf32) -> !fir.ref> {name = "c"} ! CHECK: %[[PRIVATE_D:.*]] = acc.private varPtr(%{{.*}} : !fir.ref>) recipe(@privatization_ref_10x10xf32) -> !fir.ref> {name = "d"} ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_C]], %[[PRIVATE_D]], %[[PRIVATE_I]] : !fir.ref>, !fir.ref>, !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop tile(2) DO i = 1, n a(i) = b(i) END DO ! CHECK: [[TILESIZE:%.*]] = arith.constant 2 : i32 ! CHECK: acc.loop {{.*}} tile({[[TILESIZE]] : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop tile(*) DO i = 1, n a(i) = b(i) END DO ! CHECK: [[TILESIZEM1:%.*]] = arith.constant -1 : i32 ! CHECK: acc.loop {{.*}} tile({[[TILESIZEM1]] : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop tile(2, 2) DO i = 1, n DO j = 1, n c(i, j) = d(i, j) END DO END DO ! CHECK: [[TILESIZE1:%.*]] = arith.constant 2 : i32 ! CHECK: [[TILESIZE2:%.*]] = arith.constant 2 : i32 ! CHECK: acc.loop {{.*}} tile({[[TILESIZE1]] : i32, [[TILESIZE2]] : i32}) control(%arg0 : i32, %arg1 : i32) = (%{{.*}} : i32, i32) to (%{{.*}} : i32, i32) step (%{{.*}} : i32, i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop tile(tileSize) DO i = 1, n a(i) = b(i) END DO ! CHECK: acc.loop {{.*}} tile({%{{.*}} : i32}) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop tile(tileSize, tileSize) DO i = 1, n DO j = 1, n c(i, j) = d(i, j) END DO END DO ! CHECK: acc.loop {{.*}} tile({%{{.*}} : i32, %{{.*}} : i32}) control(%arg0 : i32, %arg1 : i32) = (%{{.*}} : i32, i32) to (%{{.*}} : i32, i32) step (%{{.*}} : i32, i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop collapse(2) DO i = 1, n DO j = 1, n c(i, j) = d(i, j) END DO END DO ! CHECK: acc.loop {{.*}} control(%arg0 : i32, %arg1 : i32) = (%{{.*}} : i32, i32) to (%{{.*}} : i32, i32) step (%{{.*}} : i32, i32) { ! CHECK: fir.store %arg0 to %{{.*}} : !fir.ref ! CHECK: fir.store %arg1 to %{{.*}} : !fir.ref ! CHECK: acc.yield ! CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type]{{.*}}} !$acc loop collapse(2) tile(tileSize) DO i = 1, n DO j = 1, n c(i, j) = d(i, j) END DO END DO ! CHECK: acc.loop {{.*}} tile({%{{.*}} : i32}) control(%arg0 : i32, %arg1 : i32) = (%{{.*}} : i32, i32) to (%{{.*}} : i32, i32) step (%{{.*}} : i32, i32) { ! CHECK: fir.store %arg0 to %{{.*}} : !fir.ref ! CHECK: fir.store %arg1 to %{{.*}} : !fir.ref ! CHECK: acc.yield ! CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type]{{.*}}} !$acc loop collapse(2) tile(tileSize, tileSize, tileSize) DO i = 1, n DO j = 1, n DO k = 1, n c(i, j) = d(i, j) END DO END DO END DO ! CHECK: acc.loop {{.*}} tile({%{{.*}} : i32, %{{.*}} : i32, %{{.*}} : i32}) control(%arg0 : i32, %arg1 : i32, %arg2 : i32) = (%{{.*}} : i32, i32, i32) to (%{{.*}} : i32, i32, i32) step (%{{.*}} : i32, i32, i32) { ! CHECK: fir.store %arg0 to %{{.*}} : !fir.ref ! CHECK: fir.store %arg1 to %{{.*}} : !fir.ref ! CHECK: fir.store %arg2 to %{{.*}} : !fir.ref ! CHECK: acc.yield ! CHECK-NEXT: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type]{{.*}}} !$acc loop collapse(3) tile(tileSize, tileSize) DO i = 1, n DO j = 1, n DO k = 1, n c(i, j) = d(i, j) END DO END DO END DO ! CHECK: acc.loop {{.*}} tile({%{{.*}} : i32, %{{.*}} : i32}) control(%arg0 : i32, %arg1 : i32, %arg2 : i32) = (%{{.*}} : i32, i32, i32) to (%{{.*}} : i32, i32, i32) step (%{{.*}} : i32, i32, i32) { ! CHECK: fir.store %arg0 to %{{.*}} : !fir.ref ! CHECK: fir.store %arg1 to %{{.*}} : !fir.ref ! CHECK: fir.store %arg2 to %{{.*}} : !fir.ref ! CHECK: acc.yield ! CHECK-NEXT: } attributes {collapse = [3], collapseDeviceType = [#acc.device_type]{{.*}}} !$acc loop DO i = 1, n !$acc loop DO j = 1, n c(i, j) = d(i, j) END DO END DO ! CHECK: acc.loop {{.*}} control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.loop {{.*}} control(%arg1 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop reduction(+:reduction_r) reduction(*:reduction_i) do i = 1, n reduction_r = reduction_r + a(i) reduction_i = 1 end do ! CHECK: %[[REDUCTION_R:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref) recipe(@reduction_add_ref_f32) -> !fir.ref {name = "reduction_r"} ! CHECK: %[[REDUCTION_I:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref) recipe(@reduction_mul_ref_i32) -> !fir.ref {name = "reduction_i"} ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: acc.loop private(%[[PRIVATE_I]] : !fir.ref) reduction(%[[REDUCTION_R]], %[[REDUCTION_I]] : !fir.ref, !fir.ref) control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop gang(dim: gangDim, static: gangStatic) DO i = 1, n a(i) = b(i) END DO ! CHECK: acc.loop gang({dim=%{{.*}}, static=%{{.*}} : i32}) {{.*}} control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop gang(dim: 1) DO i = 1, n a(i) = b(i) END DO ! CHECK: acc.loop gang({dim={{.*}} : i32}) {{.*}} control(%arg0 : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) { ! CHECK: acc.yield ! CHECK-NEXT: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} !$acc loop do 100 i=0, n 100 continue ! CHECK: acc.loop !$acc loop gang device_type(nvidia) gang(8) DO i = 1, n END DO ! CHECK: acc.loop gang([#acc.device_type], {num=%c8{{.*}} : i32} [#acc.device_type]) !$acc loop device_type(nvidia, default) gang DO i = 1, n END DO ! CHECK: acc.loop gang([#acc.device_type, #acc.device_type]) end program subroutine sub1(i, j, k) integer :: i,j,k integer :: a(i,j,k) !$acc parallel loop do concurrent (i=1:10,j=1:100,k=1:200) a(i,j,k) = a(i,j,k) + 1 end do end subroutine ! CHECK: func.func @_QPsub1 ! CHECK-SAME: %[[ARG_I:.*]]: !fir.ref {fir.bindc_name = "i"} ! CHECK-SAME: %[[ARG_J:.*]]: !fir.ref {fir.bindc_name = "j"} ! CHECK-SAME: %[[ARG_K:.*]]: !fir.ref {fir.bindc_name = "k"} ! CHECK: %[[DC_I:.*]]:2 = hlfir.declare %[[ARG_I]] dummy_scope %0 ! CHECK: %[[DC_J:.*]]:2 = hlfir.declare %[[ARG_J]] dummy_scope %0 ! CHECK: %[[DC_K:.*]]:2 = hlfir.declare %[[ARG_K]] dummy_scope %0 ! CHECK: acc.parallel combined(loop) ! CHECK: %[[P_I:.*]] = acc.private varPtr(%[[DC_I]]#0 : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} ! CHECK: %[[P_J:.*]] = acc.private varPtr(%[[DC_J]]#0 : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "j"} ! CHECK: %[[P_K:.*]] = acc.private varPtr(%[[DC_K]]#0 : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "k"} ! CHECK: acc.loop combined(parallel) private(%[[P_I]], %[[P_J]], %[[P_K]] : !fir.ref, !fir.ref, !fir.ref) control(%{{.*}} : i32, %{{.*}} : i32, %{{.*}} : i32) = (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32) to (%c10{{.*}}, %c100{{.*}}, %c200{{.*}} : i32, i32, i32) step (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32) ! CHECK: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]}