Skip to content

Commit

Permalink
[flang][NFC] Add IO related lowering tests
Browse files Browse the repository at this point in the history
This patch adds lowering tests for IO related use cases.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D122321

Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
  • Loading branch information
3 people committed Mar 23, 2022
1 parent dd3e542 commit 3ea6727
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
109 changes: 109 additions & 0 deletions flang/test/Lower/io-item-list.f90
@@ -0,0 +1,109 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s

! Test that IO item list are lowered and passed correctly

! CHECK-LABEL: func @_QPpass_assumed_len_char_unformatted_io
subroutine pass_assumed_len_char_unformatted_io(c)
character(*) :: c
! CHECK: %[[unbox:.*]]:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
write(1, rec=1) c
! CHECK: %[[box:.*]] = fir.embox %[[unbox]]#0 typeparams %[[unbox]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
! CHECK: %[[castedBox:.*]] = fir.convert %[[box]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
! CHECK: fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[castedBox]]) : (!fir.ref<i8>, !fir.box<none>) -> i1
end

! CHECK-LABEL: func @_QPpass_assumed_len_char_array
subroutine pass_assumed_len_char_array(carray)
character(*) :: carray(2, 3)
! CHECK-DAG: %[[unboxed:.*]]:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
! CHECK-DAG: %[[buffer:.*]] = fir.convert %[[unboxed]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<2x3x!fir.char<1,?>>>
! CHECK-DAG: %[[c2:.*]] = arith.constant 2 : index
! CHECK-DAG: %[[c3:.*]] = arith.constant 3 : index
! CHECK-DAG: %[[shape:.*]] = fir.shape %[[c2]], %[[c3]] : (index, index) -> !fir.shape<2>
! CHECK: %[[box:.*]] = fir.embox %[[buffer]](%[[shape]]) typeparams %[[unboxed]]#1 : (!fir.ref<!fir.array<2x3x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.box<!fir.array<2x3x!fir.char<1,?>>>
! CHECK: %[[descriptor:.*]] = fir.convert %[[box]] : (!fir.box<!fir.array<2x3x!fir.char<1,?>>>) -> !fir.box<none>
! CHECK: fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[descriptor]]) : (!fir.ref<i8>, !fir.box<none>) -> i1
print *, carray
end

! CHECK-LABEL: func @_QPpass_array_slice_read(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
! CHECK: %[[VAL_1:.*]] = arith.constant 5 : i32
! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,
! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.char<1,{{[0-9]+}}>>) -> !fir.ref<i8>
! CHECK: %[[VAL_4:.*]] = arith.constant {{[0-9]+}} : i32
! CHECK: %[[VAL_5:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_1]], %[[VAL_3]], %[[VAL_4]]) : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
! CHECK: %[[VAL_6:.*]] = arith.constant 101 : i64
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i64) -> index
! CHECK: %[[VAL_8:.*]] = arith.constant 2 : i64
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> index
! CHECK: %[[VAL_10:.*]] = arith.constant 200 : i64
! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index
! CHECK: %[[VAL_12:.*]] = fir.slice %[[VAL_7]], %[[VAL_11]], %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
! CHECK: %[[VAL_13:.*]] = fir.rebox %[[VAL_0]] {{\[}}%[[VAL_12]]] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
! CHECK: %[[VAL_15:.*]] = fir.call @_FortranAioInputDescriptor(%[[VAL_5]], %[[VAL_14]]) : (!fir.ref<i8>, !fir.box<none>) -> i1
! CHECK: %[[VAL_16:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_5]]) : (!fir.ref<i8>) -> i32
! CHECK: return
! CHECK: }

subroutine pass_array_slice_read(x)
real :: x(:)
read(5, *) x(101:200:2)
end

! CHECK-LABEL: func @_QPpass_array_slice_write(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
! CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32
! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,
! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.char<1,{{[0-9]+}}>>) -> !fir.ref<i8>
! CHECK: %[[VAL_4:.*]] = arith.constant {{[0-9]+}} : i32
! CHECK: %[[VAL_5:.*]] = fir.call @_FortranAioBeginUnformattedOutput(%[[VAL_1]], %[[VAL_3]], %[[VAL_4]]) : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32
! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> i64
! CHECK: %[[VAL_8:.*]] = fir.call @_FortranAioSetRec(%[[VAL_5]], %[[VAL_7]]) : (!fir.ref<i8>, i64) -> i1
! CHECK: %[[VAL_9:.*]] = arith.constant 101 : i64
! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i64) -> index
! CHECK: %[[VAL_11:.*]] = arith.constant 2 : i64
! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i64) -> index
! CHECK: %[[VAL_13:.*]] = arith.constant 200 : i64
! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i64) -> index
! CHECK: %[[VAL_15:.*]] = fir.slice %[[VAL_10]], %[[VAL_14]], %[[VAL_12]] : (index, index, index) -> !fir.slice<1>
! CHECK: %[[VAL_16:.*]] = fir.rebox %[[VAL_0]] {{\[}}%[[VAL_15]]] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
! CHECK: %[[VAL_18:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_5]], %[[VAL_17]]) : (!fir.ref<i8>, !fir.box<none>) -> i1
! CHECK: %[[VAL_19:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_5]]) : (!fir.ref<i8>) -> i32
! CHECK: return
! CHECK: }

subroutine pass_array_slice_write(x)
real :: x(:)
write(1, rec=1) x(101:200:2)
end


! CHECK-LABEL: func @_QPpass_vector_subscript_write(
! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.array<100xf32>>{{.*}}, %[[j:.*]]: !fir.ref<!fir.array<10xi32>>{{.*}})
subroutine pass_vector_subscript_write(x, j)
! Check that a temp is made for array with vector subscript in output IO.
integer :: j(10)
real :: x(100)
! CHECK: %[[jload:.*]] = fir.array_load %[[j]](%{{.*}}) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.array<10xi32>
! CHECK: %[[xload:.*]] = fir.array_load %[[x]](%{{.*}}) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.array<100xf32>
! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<10xf32>
! CHECK: %[[tempload:.*]] = fir.array_load %[[temp]](%{{.*}}) : (!fir.heap<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.array<10xf32>
! CHECK: %[[copy:.*]] = fir.do_loop
! CHECK: %[[jfetch:.*]] = fir.array_fetch %[[jload]], %{{.*}} : (!fir.array<10xi32>, index) -> i32
! CHECK: %[[jcast:.*]] = fir.convert %[[jfetch]] : (i32) -> index
! CHECK: %[[jindex:.*]] = arith.subi %[[jcast]], %c1{{.*}} : index
! CHECK: %[[xfetch:.*]] = fir.array_fetch %[[xload]], %[[jindex]] : (!fir.array<100xf32>, index) -> f32
! CHECK: %[[update:.*]] = fir.array_update %{{.*}}, %[[xfetch]], %{{.*}} : (!fir.array<10xf32>, f32, index) -> !fir.array<10xf32>
! CHECK: fir.result %[[update]] : !fir.array<10xf32>
! CHECK: }
! CHECK: fir.array_merge_store %[[tempload]], %[[copy]] to %[[temp]] : !fir.array<10xf32>, !fir.array<10xf32>, !fir.heap<!fir.array<10xf32>>
! CHECK: %[[embox:.*]] = fir.embox %[[temp]](%{{.*}}) : (!fir.heap<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xf32>>
! CHECK: %[[boxCast:.*]] = fir.convert %[[embox]] : (!fir.box<!fir.array<10xf32>>) -> !fir.box<none>
! CHECK: fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[boxCast]]) : (!fir.ref<i8>, !fir.box<none>) -> i1
! CHECK: fir.freemem %[[temp]]
write(1, rec=1) x(j)
end
43 changes: 43 additions & 0 deletions flang/test/Lower/io-statement-clean-ups.f90
@@ -0,0 +1,43 @@
! Test that any temps generated for IO options are deallocated at the right
! time (after they are used, but before exiting the block where they were
! created).
! RUN: bbc -emit-fir -o - %s | FileCheck %s

! CHECK-LABEL: func @_QPtest_temp_io_options(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32>{{.*}}) {
subroutine test_temp_io_options(status)
interface
function gen_temp_character()
character(:), allocatable :: gen_temp_character
end function
end interface
integer :: status
open (10, encoding=gen_temp_character(), file=gen_temp_character(), pad=gen_temp_character(), iostat=status)
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
! CHECK: fir.call @_FortranAioBeginOpenUnit
! CHECK: %[[VAL_15:.*]] = fir.call @_QPgen_temp_character() : () -> !fir.box<!fir.heap<!fir.char<1,?>>>
! CHECK: fir.save_result %[[VAL_15]] to %[[VAL_3]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[VAL_21:.*]] = fir.call @_FortranAioSetEncoding
! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
! CHECK: fir.freemem %[[VAL_23]]
! CHECK: fir.if %[[VAL_21]] {
! CHECK: %[[VAL_27:.*]] = fir.call @_QPgen_temp_character() : () -> !fir.box<!fir.heap<!fir.char<1,?>>>
! CHECK: fir.save_result %[[VAL_27]] to %[[VAL_2]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[VAL_33:.*]] = fir.call @_FortranAioSetFile
! CHECK: %[[VAL_34:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_34]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
! CHECK: fir.freemem %[[VAL_35]]
! CHECK: fir.if %[[VAL_33]] {
! CHECK: %[[VAL_39:.*]] = fir.call @_QPgen_temp_character() : () -> !fir.box<!fir.heap<!fir.char<1,?>>>
! CHECK: fir.save_result %[[VAL_39]] to %[[VAL_1]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: fir.call @_FortranAioSetPad
! CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
! CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_46]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
! CHECK: fir.freemem %[[VAL_47]]
! CHECK: }
! CHECK: }
! CHECK: fir.call @_FortranAioEndIoStatement
end subroutine

0 comments on commit 3ea6727

Please sign in to comment.