mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 04:16:46 +00:00

Currently, the helpers to get fir::ExtendedValue out of hlfir::Entity use hlfir.declare second result (`#1`) in most cases. This is because this result is the same as the input and matches what FIR was getting before lowering to HLFIR. But this creates odd situations when both hlfir.declare are raw pointers and either result ends-up being used in the IR depending on whether the code was generated by a helper using fir::ExtendedValue, or via "pure HLFIR" helpers using the first result. This will typically prevent simple CSE and easy identification that two operation (e.g load/store) are touching the exact same memory location without using alias analysis or "manual detection" (looking for common hlfir.declare defining op). Hence, when hlfir.declare results are both raw pointers, use `#0` when producing `fir::ExtendedValue`. When `#0` is a fir.box, keep using `#1` because these are not the same. The only code change is in HLFIRTools.cpp and is pretty small, but there is a big test fallout of `#1` to `#0`.
334 lines
19 KiB
Fortran
334 lines
19 KiB
Fortran
! Test correct deallocation of intent(out) allocatables.
|
|
! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes=CHECK,FIR
|
|
! RUN: bbc -emit-hlfir %s -o - -I nw | FileCheck %s --check-prefixes=CHECK,HLFIR
|
|
|
|
module mod1
|
|
type, bind(c) :: t1
|
|
integer :: i
|
|
end type
|
|
|
|
type :: t
|
|
integer :: a
|
|
end type
|
|
|
|
type, extends(t) :: t2
|
|
integer :: b
|
|
end type
|
|
|
|
interface
|
|
subroutine sub3(a) bind(c)
|
|
integer, intent(out), allocatable :: a(:)
|
|
end subroutine
|
|
end interface
|
|
|
|
interface
|
|
subroutine sub7(t) bind(c)
|
|
import :: t1
|
|
type(t1), allocatable, intent(out) :: t
|
|
end subroutine
|
|
end interface
|
|
|
|
contains
|
|
subroutine sub0()
|
|
integer, allocatable :: a(:)
|
|
allocate(a(10))
|
|
call sub1(a)
|
|
end subroutine
|
|
|
|
subroutine sub1(a)
|
|
integer, intent(out), allocatable :: a(:)
|
|
end subroutine
|
|
|
|
! Make sure there is no deallocation of the allocatable intent(out) on the
|
|
! caller side.
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub0()
|
|
! CHECK-NOT: fir.freemem
|
|
! CHECK: fir.call @_QMmod1Psub1
|
|
|
|
! Check inline deallocation of allocatable intent(out) on the callee side.
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub1(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"})
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub1Ea"
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : index
|
|
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
|
|
! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: }
|
|
|
|
subroutine sub2()
|
|
integer, allocatable :: a(:)
|
|
allocate(a(10))
|
|
call sub3(a)
|
|
end subroutine
|
|
|
|
! Check inlined deallocation of allocatble intent(out) on the caller side for BIND(C).
|
|
|
|
! FIR-LABEL: func.func @_QMmod1Psub2()
|
|
! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "a", uniq_name = "_QMmod1Fsub2Ea"}
|
|
! FIR: %[[BOX_ALLOC:.*]] = fir.alloca !fir.heap<!fir.array<?xi32>> {uniq_name = "_QMmod1Fsub2Ea.addr"}
|
|
! FIR: %[[BOX_ADDR:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
|
|
! FIR: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
|
|
! FIR: %[[C0:.*]] = arith.constant 0 : i64
|
|
! FIR: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! FIR: fir.if %[[IS_ALLOCATED]] {
|
|
! FIR: %[[LOAD:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
|
|
! FIR: fir.freemem %[[LOAD]] : !fir.heap<!fir.array<?xi32>>
|
|
! FIR: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
! FIR: fir.store %[[ZERO]] to %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
|
|
! FIR: }
|
|
! FIR: %[[LOAD:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
|
|
! FIR: %{{.*}} = fir.embox %[[LOAD]](%{{.*}}) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<
|
|
! FIR: fir.call @sub3(%[[BOX]]) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> ()
|
|
|
|
! HLFIR-LABEL: func.func @_QMmod1Psub2(
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub2Ea"
|
|
! HLFIR: %[[BOX:.*]] = fir.load %[[ARG0]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! HLFIR: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
|
|
! HLFIR: %[[C0:.*]] = arith.constant 0 : i64
|
|
! HLFIR: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! HLFIR: fir.if %[[IS_ALLOCATED]] {
|
|
! HLFIR: %[[BOX:.*]] = fir.load %[[ARG0]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! HLFIR: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
|
|
! HLFIR: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
! HLFIR: %[[C0:.*]] = arith.constant 0 : index
|
|
! HLFIR: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
|
|
! HLFIR: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
! HLFIR: fir.store %[[EMBOX]] to %[[ARG0]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! HLFIR: fir.call @sub3(%[[ARG0]]#0) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> ()
|
|
|
|
subroutine sub4()
|
|
type(t1), allocatable :: t
|
|
call sub5(t)
|
|
end subroutine
|
|
|
|
subroutine sub5(t)
|
|
type(t1), allocatable, intent(out) :: t
|
|
end subroutine
|
|
|
|
! Make sure there is no deallocation runtime call of the allocatable intent(out)
|
|
! on the caller side.
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub4()
|
|
! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>> {bindc_name = "t", uniq_name = "_QMmod1Fsub4Et"}
|
|
! HLFIR: %[[BOX:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub4Et"
|
|
! CHECK-NOT: fir.call @_FortranAAllocatableDeallocate
|
|
! CHECK: fir.call @_QMmod1Psub5(%[[BOX]]{{[#0]*}}) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> ()
|
|
|
|
! Check deallocation of allocatble intent(out) on the callee side. Deallocation
|
|
! is done with a runtime call.
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub5(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>> {fir.bindc_name = "t"})
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub5Et"
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>) -> !fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> !fir.ref<!fir.box<none>>
|
|
! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
|
|
|
|
subroutine sub6()
|
|
type(t1), allocatable :: t
|
|
call sub7(t)
|
|
end subroutine
|
|
|
|
! Check deallocation of allocatble intent(out) on the caller side for BIND(C).
|
|
! Deallocation is done with a runtime call.
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub6()
|
|
! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>> {bindc_name = "t", uniq_name = "_QMmod1Fsub6Et"}
|
|
! HLFIR: %[[BOX:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub6Et"
|
|
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]]{{[#0]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> !fir.ref<!fir.box<none>>
|
|
! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
|
|
! CHECK: fir.call @sub7(%[[BOX]]{{[#0]*}}) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> ()
|
|
|
|
subroutine sub8()
|
|
integer, allocatable :: a(:)
|
|
allocate(a(10))
|
|
call sub9(a)
|
|
end subroutine
|
|
|
|
subroutine sub9(a)
|
|
integer, intent(out), allocatable, optional :: a(:)
|
|
end subroutine
|
|
|
|
! Make sure there is no deallocation of the allocatable intent(out) on the
|
|
! caller side.
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub8()
|
|
! CHECK-NOT: fir.freemem
|
|
! CHECK: fir.call @_QMmod1Psub9
|
|
|
|
! Check inline deallocation of optional allocatable intent(out) on the callee side.
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub9(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a", fir.optional})
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub9Ea"
|
|
! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> i1
|
|
! CHECK: fir.if %[[IS_PRESENT]] {
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : index
|
|
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
|
|
! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: }
|
|
! CHECK: }
|
|
|
|
subroutine sub10(a)
|
|
integer, intent(out), allocatable :: a(:)
|
|
|
|
entry sub11
|
|
end subroutine
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub10(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub10Ea"
|
|
! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : index
|
|
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
|
|
! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: }
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub11() {
|
|
! CHECK-NOT: fir.freemem
|
|
|
|
subroutine sub12(a)
|
|
integer, intent(out), allocatable :: a(:)
|
|
entry sub13(a)
|
|
end subroutine
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub12(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub12Ea"
|
|
! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : index
|
|
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
|
|
! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: }
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub13(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub12Ea"
|
|
! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : index
|
|
! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
|
|
! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
! CHECK: }
|
|
|
|
|
|
subroutine sub14(p)
|
|
class(t), intent(out), allocatable :: p
|
|
end subroutine
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub14(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>> {fir.bindc_name = "p"}) {
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub14Ep"
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>) -> !fir.heap<!fir.type<_QMmod1Tt{a:i32}>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMmod1Tt{a:i32}>
|
|
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
|
|
! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMmod1Tt{a:i32}>>) -> !fir.ref<none>
|
|
! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
|
|
! CHECK: }
|
|
|
|
subroutine sub15(p)
|
|
class(*), intent(out), allocatable :: p
|
|
end subroutine
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub15(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<none>>> {fir.bindc_name = "p"}) {
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub15Ep"
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.class<!fir.heap<none>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<none>>) -> !fir.heap<none>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<none>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[NULL_TYPE_DESC:.*]] = fir.zero_bits !fir.ref<none>
|
|
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
|
|
! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[NULL_TYPE_DESC]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
|
|
! CHECK: }
|
|
|
|
subroutine sub16(p)
|
|
class(t), optional, intent(out), allocatable :: p
|
|
end subroutine
|
|
|
|
! CHECK-LABEL: func.func @_QMmod1Psub16(
|
|
! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>> {fir.bindc_name = "p", fir.optional}) {
|
|
! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub16Ep"
|
|
! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> i1
|
|
! CHECK: fir.if %[[IS_PRESENT]] {
|
|
! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#0]*}} : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>
|
|
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>) -> !fir.heap<!fir.type<_QMmod1Tt{a:i32}>>
|
|
! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>) -> i64
|
|
! CHECK: %[[C0:.*]] = arith.constant 0 : i64
|
|
! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
|
|
! CHECK: fir.if %[[IS_ALLOCATED]] {
|
|
! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMmod1Tt{a:i32}>
|
|
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#0]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
|
|
! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMmod1Tt{a:i32}>>) -> !fir.ref<none>
|
|
! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%[[BOX_NONE]], %[[TYPE_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
|
|
! CHECK: }
|
|
! CHECK: }
|
|
|
|
end module
|