blob: 62bb75e08392ce225765b49a30e9bec3081a195a [file] [edit]
! Test lowering of references to pointers
! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
! Assigning/reading to scalar pointer target.
! CHECK-LABEL: func @_QPscal_ptr(
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.ptr<f32>>>{{.*}})
subroutine scal_ptr(p)
real, pointer :: p
real :: x
! CHECK: %[[pdecl:.*]]:2 = hlfir.declare %[[arg0]]{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFscal_ptrEp"}
! CHECK: %[[boxload:.*]] = fir.load %[[pdecl]]#0
! CHECK: %[[addr:.*]] = fir.box_addr %[[boxload]]
! CHECK: hlfir.assign %{{.*}} to %[[addr]]
p = 3.
! CHECK: %[[boxload2:.*]] = fir.load %[[pdecl]]#0
! CHECK: %[[addr2:.*]] = fir.box_addr %[[boxload2]]
! CHECK: %[[val:.*]] = fir.load %[[addr2]]
! CHECK: hlfir.assign %[[val]] to %{{.*}}
x = p
end subroutine
! Assigning/reading scalar character pointer target.
! CHECK-LABEL: func @_QPchar_ptr(
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.char<1,12>>>>{{.*}})
subroutine char_ptr(p)
character(12), pointer :: p
character(12) :: x
! CHECK: %[[pdecl:.*]]:2 = hlfir.declare %[[arg0]]{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFchar_ptrEp"}
! CHECK: %[[straddr:.*]] = fir.address_of(@_QQclX68656C6C6F20776F726C6421) : !fir.ref<!fir.char<1,12>>
! CHECK: %[[str:.*]]:2 = hlfir.declare %[[straddr]] typeparams %{{.*}} {{.*}} : (!fir.ref<!fir.char<1,12>>, index) -> (!fir.ref<!fir.char<1,12>>, !fir.ref<!fir.char<1,12>>)
! CHECK: %[[boxload:.*]] = fir.load %[[pdecl]]#0
! CHECK: %[[addr:.*]] = fir.box_addr %[[boxload]]
! CHECK: hlfir.assign %[[str]]#0 to %[[addr]] : !fir.ref<!fir.char<1,12>>, !fir.ptr<!fir.char<1,12>>
p = "hello world!"
! CHECK: %[[boxload2:.*]] = fir.load %[[pdecl]]#0
! CHECK: %[[addr2:.*]] = fir.box_addr %[[boxload2]]
! CHECK: hlfir.assign %[[addr2]] to %{{.*}} : !fir.ptr<!fir.char<1,12>>, !fir.ref<!fir.char<1,12>>
x = p
end subroutine
! Reading from pointer in array expression
! CHECK-LABEL: func @_QParr_ptr_read(
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>{{.*}})
subroutine arr_ptr_read(p)
real, pointer :: p(:)
real :: x(100)
! CHECK: %[[pdecl:.*]]:2 = hlfir.declare %[[arg0]]{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFarr_ptr_readEp"}
! CHECK: %[[xdecl:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFarr_ptr_readEx"}
! CHECK: %[[boxload:.*]] = fir.load %[[pdecl]]#0
! CHECK: hlfir.assign %[[boxload]] to %[[xdecl]]#0 : !fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.ref<!fir.array<100xf32>>
x = p
end subroutine
! Reading from contiguous pointer in array expression
! CHECK-LABEL: func @_QParr_contig_ptr_read(
! CHECK-SAME: %[[arg0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {{{.*}}, fir.contiguous})
subroutine arr_contig_ptr_read(p)
real, pointer, contiguous :: p(:)
real :: x(100)
! CHECK: %[[pdecl:.*]]:2 = hlfir.declare %[[arg0]]{{.*}} {fortran_attrs = #fir.var_attrs<contiguous, pointer>, uniq_name = "_QFarr_contig_ptr_readEp"}
! CHECK: %[[xdecl:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFarr_contig_ptr_readEx"}
! CHECK: %[[boxload:.*]] = fir.load %[[pdecl]]#0
! CHECK: hlfir.assign %[[boxload]] to %[[xdecl]]#0 : !fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.ref<!fir.array<100xf32>>
x = p
end subroutine
! Assigning to pointer target in array expression
! CHECK-LABEL: func @_QParr_ptr_target_write(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>{{.*}}) {
! CHECK: %[[VAL_P:.*]]:2 = hlfir.declare %[[VAL_0]]{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFarr_ptr_target_writeEp"}
! CHECK: %[[VAL_X:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFarr_ptr_target_writeEx"}
! CHECK: %[[VAL_PLOAD:.*]] = fir.load %[[VAL_P]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_DESIG:.*]] = hlfir.designate %[[VAL_PLOAD]] (%c2{{.*}}:%c601{{.*}}:%c6{{.*}}) shape %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<100xf32>>
! CHECK: hlfir.assign %[[VAL_X]]#0 to %[[VAL_DESIG]] : !fir.ref<!fir.array<100xf32>>, !fir.box<!fir.array<100xf32>>
! CHECK: return
! CHECK: }
subroutine arr_ptr_target_write(p)
real, pointer :: p(:)
real :: x(100)
p(2:601:6) = x
end subroutine
! Assigning to contiguous pointer target in array expression
! CHECK-LABEL: func @_QParr_contig_ptr_target_write(
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {{{.*}}, fir.contiguous}) {
! CHECK: %[[VAL_P:.*]]:2 = hlfir.declare %[[VAL_0]]{{.*}} {fortran_attrs = #fir.var_attrs<contiguous, pointer>, uniq_name = "_QFarr_contig_ptr_target_writeEp"}
! CHECK: %[[VAL_X:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFarr_contig_ptr_target_writeEx"}
! CHECK: %[[VAL_PLOAD:.*]] = fir.load %[[VAL_P]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_DESIG:.*]] = hlfir.designate %[[VAL_PLOAD]] (%c2{{.*}}:%c601{{.*}}:%c6{{.*}}) shape %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<100xf32>>
! CHECK: hlfir.assign %[[VAL_X]]#0 to %[[VAL_DESIG]] : !fir.ref<!fir.array<100xf32>>, !fir.box<!fir.array<100xf32>>
! CHECK: return
! CHECK: }
subroutine arr_contig_ptr_target_write(p)
real, pointer, contiguous :: p(:)
real :: x(100)
p(2:601:6) = x
end subroutine
! CHECK-LABEL: func @_QPpointer_result_as_value
subroutine pointer_result_as_value()
! Test that function pointer results used as values are correctly loaded.
interface
function returns_int_pointer()
integer, pointer :: returns_int_pointer
end function
end interface
! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = ".result"}
! CHECK: %[[VAL_6:.*]] = fir.call @_QPreturns_int_pointer() {{.*}}: () -> !fir.box<!fir.ptr<i32>>
! CHECK: fir.save_result %[[VAL_6]] to %[[VAL_0]] : !fir.box<!fir.ptr<i32>>, !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[VAL_RES:.*]]:2 = hlfir.declare %[[VAL_0]] {{.*}} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_RES]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: fir.load %[[VAL_8]] : !fir.ptr<i32>
print *, returns_int_pointer()
end subroutine