Files
TheRock/compiler/amd-llvm/flang/test/Lower/OpenACC/acc-unstructured.f90
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

313 lines
8.8 KiB
Fortran

! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
subroutine test_unstructured1(a, b, c)
integer :: i, j, k
real :: a(:,:,:), b(:,:,:), c(:,:,:)
!$acc data copy(a, b, c)
!$acc kernels
a(:,:,:) = 0.0
!$acc end kernels
!$acc kernels
do i = 1, 10
do j = 1, 10
do k = 1, 10
end do
end do
end do
!$acc end kernels
do i = 1, 10
do j = 1, 10
do k = 1, 10
end do
end do
if (a(1,2,3) > 10) stop 'just to be unstructured'
end do
!$acc end data
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured1
! CHECK: acc.data
! CHECK: acc.kernels
! CHECK: acc.kernels
! CHECK: fir.call @_FortranAStopStatementText
subroutine test_unstructured2(a, b, c)
integer :: i, j, k
real :: a(:,:,:), b(:,:,:), c(:,:,:)
!$acc parallel loop
do i = 1, 10
do j = 1, 10
do k = 1, 10
if (a(1,2,3) > 10) stop 'just to be unstructured'
end do
end do
end do
! CHECK-LABEL: func.func @_QPtest_unstructured2
! CHECK: acc.parallel
! CHECK: acc.loop combined(parallel) private(%{{.*}} : !fir.ref<i32>) {
! CHECK: fir.call @_FortranAStopStatementText
! CHECK: acc.yield
! CHECK: acc.yield
! CHECK: } attributes {independent = [#acc.device_type<none>], unstructured}
! CHECK: acc.yield
end subroutine
subroutine test_unstructured3(a, b, c)
integer :: i, j, k
real :: a(:,:,:), b(:,:,:), c(:,:,:)
!$acc parallel
do i = 1, 10
do j = 1, 10
do k = 1, 10
if (a(1,2,3) > 10) stop 'just to be unstructured'
end do
end do
end do
!$acc end parallel
! CHECK-LABEL: func.func @_QPtest_unstructured3
! CHECK: acc.parallel
! CHECK: fir.call @_FortranAStopStatementText
! CHECK: acc.yield
! CHECK: acc.yield
end subroutine
! Test that acc.data is still created when there are no data clauses but the
! construct contains unstructured control flow. Without this, the early return
! in genACCDataOp skips acc.data creation, leaving orphaned blocks.
subroutine test_unstructured4(a, n)
integer :: n, i, j
real :: a(:)
logical :: use_gpu
use_gpu = .true.
!$acc data if(use_gpu)
do i = 1, n
do j = 1, n
if (a(j) > 0.0) stop 'unstructured'
end do
end do
!$acc end data
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured4
! CHECK: acc.data if(%{{.*}}) {
! CHECK: fir.call @_FortranAStopStatementText
! CHECK: acc.terminator
! CHECK: }
! Test that GOTO exiting acc.data (one level) generates acc.terminator
! instead of an invalid cross-region branch.
subroutine test_unstructured5(a, n)
integer :: n, i, j
real :: a(:)
logical :: use_gpu
use_gpu = .true.
!$acc data if(use_gpu)
do i = 1, n
do j = 1, n
if (a(j) > 0.0) goto 999
end do
end do
!$acc end data
999 continue
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured5
! CHECK: acc.data if(%{{.*}}) {
! CHECK: fir.store %{{.*}} to %{{.*}} : !fir.ref<i32>
! CHECK: acc.terminator
! CHECK: acc.terminator
! CHECK: }
! CHECK: arith.cmpi eq
! CHECK: cf.cond_br
! Test that GOTO exiting acc.loop (one level) generates acc.yield
! instead of an invalid cross-region branch.
subroutine test_unstructured6(N, A, B)
implicit real*8 (a-h, o-z)
!$acc routine gang
dimension A(*), B(*)
!$acc loop gang vector
do 100 i = 1, N
!$acc loop seq
do 10 j = 1, 1000
if (A(i) .gt. B(i)) goto 20
10 continue
20 B(i) = A(i)
100 continue
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured6
! CHECK: acc.loop gang vector
! CHECK: acc.loop
! CHECK: arith.cmpf ogt
! CHECK: fir.store %{{.*}} to %{{.*}} : !fir.ref<i32>
! CHECK: acc.yield
! CHECK: } attributes {seq = [#acc.device_type<none>], unstructured}
! Test GOTO exiting acc.loop with intermediate code between loop end and
! target. A jump table (exit selector + dispatch) skips the intermediate code.
subroutine test_unstructured7(A, B, C, N)
implicit real*8 (a-h, o-z)
!$acc routine gang
dimension A(*), B(*), C(*)
!$acc loop gang vector
do 100 i = 1, N
!$acc loop seq
do 10 j = 1, 1000
if (A(i) .gt. B(i)) goto 20
10 continue
C(i) = 999.0
20 B(i) = A(i)
100 continue
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured7
! CHECK: acc.loop gang vector
! Inner loop stores exit selector and yields:
! CHECK: acc.loop
! CHECK: fir.store %{{.*}} to %{{.*}} : !fir.ref<i32>
! CHECK: acc.yield
! CHECK: } attributes {seq = [#acc.device_type<none>], unstructured}
! Jump table after inner loop:
! CHECK: fir.load %{{.*}} : !fir.ref<i32>
! CHECK: arith.cmpi eq
! CHECK: cf.cond_br
! Intermediate code on fall-through path:
! CHECK: arith.constant 9.990000e+02
! Test GOTO exiting acc.data with intermediate code. Jump table dispatches
! after the acc.data op.
subroutine test_unstructured8(a, n)
integer :: n, i, j
real :: a(:)
logical :: use_gpu
use_gpu = .true.
!$acc data if(use_gpu)
do i = 1, n
do j = 1, n
if (a(j) > 0.0) goto 999
end do
end do
a(1) = -1.0
!$acc end data
999 continue
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured8
! Inside acc.data, GOTO stores exit selector and terminates:
! CHECK: acc.data if(%{{.*}}) {
! CHECK: fir.store %{{.*}} to %{{.*}} : !fir.ref<i32>
! CHECK: acc.terminator
! CHECK: acc.terminator
! CHECK: }
! Jump table after acc.data:
! CHECK: fir.load %{{.*}} : !fir.ref<i32>
! CHECK: arith.cmpi eq
! CHECK: cf.cond_br
! Test that `acc parallel loop collapse(N)` whose body has an early-exit
! (here, `if (cond) then ... cycle ... end if`) lowers cleanly. The
! corresponding acc.loop must privatize all N induction variables, carry
! both `collapse = [N]` and `unstructured` attributes, and emit the
! iteration mechanics for all N levels as explicit cf inside the body.
! Reproducer derived from lorado issue #2856.
subroutine test_unstructured_collapse_cycle(a)
integer :: i, j, jdiag
real(8) :: a(:,:)
jdiag = 4
!$acc parallel loop collapse(2) copy(a)
do j = 1, 8
do i = 1, 8
if (i == jdiag) then
a(i, j) = 0.0d0
cycle
end if
a(i, j) = real(i + j, 8)
end do
end do
!$acc end parallel loop
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured_collapse_cycle
! CHECK: acc.parallel combined(loop)
! Both induction variables (j and i) are privatized:
! CHECK: %[[PRIVJ:.*]] = acc.private varPtr(%{{.*}} : !fir.ref<i32>) recipe(@privatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "j"}
! CHECK: %[[PRIVI:.*]] = acc.private varPtr(%{{.*}} : !fir.ref<i32>) recipe(@privatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "i"}
! No control(...) on acc.loop — bounds are not on the op:
! CHECK: acc.loop combined(parallel) private(%[[PRIVJ]], %[[PRIVI]] : !fir.ref<i32>, !fir.ref<i32>) {
! Outer loop trip-count test (j) emitted as cf:
! CHECK: arith.cmpi sgt
! CHECK: cf.cond_br
! Inner loop trip-count test (i) emitted as cf:
! CHECK: arith.cmpi sgt
! CHECK: cf.cond_br
! The if/cycle is a structured cf branch in the body:
! CHECK: arith.cmpi eq
! CHECK: cf.cond_br
! CHECK: acc.yield
! CHECK: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>], independent = [#acc.device_type<none>], unstructured}
! Test that `acc parallel loop collapse(N)` lowers cleanly when the early-exit
! is a STOP (the form already covered for collapse=1 by test_unstructured2).
subroutine test_unstructured_collapse_stop(a)
integer :: i, j, k
real :: a(:,:,:)
!$acc parallel loop collapse(3)
do i = 1, 10
do j = 1, 10
do k = 1, 10
if (a(1,2,3) > 10) stop 'just to be unstructured'
end do
end do
end do
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured_collapse_stop
! All three IVs privatized:
! CHECK: acc.private varPtr(%{{.*}} : !fir.ref<i32>) recipe(@privatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "i"}
! CHECK: acc.private varPtr(%{{.*}} : !fir.ref<i32>) recipe(@privatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "j"}
! CHECK: acc.private varPtr(%{{.*}} : !fir.ref<i32>) recipe(@privatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "k"}
! CHECK: acc.loop combined(parallel) private(%{{.*}}, %{{.*}}, %{{.*}} : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>) {
! CHECK: fir.call @_FortranAStopStatementText
! CHECK: } attributes {collapse = [3], collapseDeviceType = [#acc.device_type<none>], independent = [#acc.device_type<none>], unstructured}
! Test orphaned `acc loop collapse(N)`
subroutine test_unstructured_collapse_loop_only(a)
integer :: i, j, jdiag
real(8) :: a(:,:)
jdiag = 4
!$acc loop collapse(2)
do j = 1, 8
do i = 1, 8
if (i == jdiag) then
a(i, j) = 0.0d0
cycle
end if
a(i, j) = real(i + j, 8)
end do
end do
end subroutine
! CHECK-LABEL: func.func @_QPtest_unstructured_collapse_loop_only
! Standalone acc.loop (no `combined(...)`):
! CHECK: acc.loop private(%{{.*}}, %{{.*}} : !fir.ref<i32>, !fir.ref<i32>) {
! CHECK: } attributes {collapse = [2], collapseDeviceType = [#acc.device_type<none>], independent = [#acc.device_type<none>], unstructured}