| ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | fir-opt --array-value-copy | fir-opt --stack-arrays | FileCheck %s |
| |
| ! In order to verify the whole MLIR pipeline, make the driver generate LLVM IR. |
| ! This is only to check that -fstack-arrays enables the stack-arrays pass so |
| ! only check the first example |
| ! RUN: %flang_fc1 -emit-llvm -flang-deprecated-no-hlfir -o - -fstack-arrays %s | FileCheck --check-prefix=LLVM-IR %s |
| |
| ! check simple array value copy case |
| subroutine array_value_copy_simple(arr) |
| integer, intent(inout) :: arr(4) |
| arr(3:4) = arr(1:2) |
| end subroutine |
| ! CHECK-LABEL: func.func @_QParray_value_copy_simple(%arg0: !fir.ref<!fir.array<4xi32>> |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: fir.alloca !fir.array<4xi32> |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| ! LLVM-IR: array_value_copy_simple |
| ! LLVM-IR-NOT: malloc |
| ! LLVM-IR-NOT: free |
| ! LLVM-IR: alloca [4 x i32] |
| ! LLVM-IR-NOT: malloc |
| ! LLVM-IR-NOT: free |
| ! LLVM-IR: ret void |
| ! LLVM-IR-NEXT: } |
| |
| ! check complex array value copy case |
| module stuff |
| type DerivedWithAllocatable |
| integer, dimension(:), allocatable :: dat |
| end type |
| |
| contains |
| subroutine array_value_copy_complex(arr) |
| type(DerivedWithAllocatable), intent(inout) :: arr(:) |
| arr(3:4) = arr(1:2) |
| end subroutine |
| end module |
| ! CHECK: func.func |
| ! CHECK-SAME: array_value_copy_complex |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: fir.alloca !fir.array<?x!fir.type<_QMstuffTderivedwithallocatable |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| subroutine parameter_array_init |
| integer, parameter :: p(100) = 42 |
| call use_p(p) |
| end subroutine |
| ! CHECK: func.func |
| ! CHECK-SAME: parameter_array_init |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: fir.alloca !fir.array<100xi32> |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| subroutine test_vector_subscripted_section_to_box(v, x) |
| interface |
| subroutine takes_box(y) |
| real :: y(:) |
| end subroutine |
| end interface |
| |
| integer :: v(:) |
| real :: x(:) |
| call takes_box(x(v)) |
| end subroutine |
| ! CHECK: func.func |
| ! CHECK-SAME: test_vector_subscripted_section_to_box |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK: fir.alloca !fir.array<?xf32> |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK: fir.call @_QPtakes_box |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| subroutine call_parenthesized_arg(x) |
| integer :: x(100) |
| call bar((x)) |
| end subroutine |
| ! CHECK: func.func |
| ! CHECK-SAME: call_parenthesized_arg |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK: fir.alloca !fir.array<100xi32> |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK: fir.call @_QPbar |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| subroutine where_allocatable_assignments(a, b) |
| integer :: a(:) |
| integer, allocatable :: b(:) |
| where(b > 0) |
| b = a |
| elsewhere |
| b(:) = 0 |
| end where |
| end subroutine |
| ! TODO: broken: passing allocation through fir.result |
| ! CHECK: func.func |
| ! CHECK-SAME: where_allocatable_assignments |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| subroutine array_constructor(a, b) |
| real :: a(5), b |
| real, external :: f |
| a = [f(b), f(b+1), f(b+2), f(b+5), f(b+11)] |
| end subroutine |
| ! TODO: broken: realloc |
| ! CHECK: func.func |
| ! CHECK-SAME: array_constructor |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| subroutine sequence(seq, n) |
| integer :: n, seq(n) |
| seq = [(i,i=1,n)] |
| end subroutine |
| ! TODO: broken: realloc |
| ! CHECK: func.func |
| ! CHECK-SAME: sequence |
| ! CHECK: return |
| ! CHECK-NEXT: } |
| |
| subroutine CFGLoop(x) |
| integer, parameter :: k = 100, m=1000000, n = k*m |
| integer :: x(n) |
| logical :: has_error |
| |
| do i=0,m-1 |
| x(k*i+1:k*(i+1)) = x(k*(i+1):k*i+1:-1) |
| if (has_error(x, k)) stop |
| end do |
| end subroutine |
| ! CHECK: func.func |
| ! CHECK-SAME: cfgloop |
| ! CHECK-NEXT: %[[MEM:.*]] = fir.alloca !fir.array<100000000xi32> |
| ! CHECK-NOT: fir.allocmem |
| ! CHECK-NOT: fir.freemem |
| ! CHECK: return |
| ! CHECK-NEXT: } |