[Clang] Make OpenMP offloading consistently use the bound architecture (#125135)
[llvm-project.git] / flang / test / Lower / intentout-deallocate.f90
blob931cf7d48885f3cfdf9c15c482962bd4ac8dc4fc
1 ! Test correct deallocation of intent(out) allocatables.
2 ! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s --check-prefixes=CHECK,FIR
3 ! RUN: bbc -emit-hlfir %s -o - -I nw | FileCheck %s --check-prefixes=CHECK,HLFIR
5 module mod1
6 type, bind(c) :: t1
7 integer :: i
8 end type
10 type :: t
11 integer :: a
12 end type
14 type, extends(t) :: t2
15 integer :: b
16 end type
18 interface
19 subroutine sub3(a) bind(c)
20 integer, intent(out), allocatable :: a(:)
21 end subroutine
22 end interface
24 interface
25 subroutine sub7(t) bind(c)
26 import :: t1
27 type(t1), allocatable, intent(out) :: t
28 end subroutine
29 end interface
31 contains
32 subroutine sub0()
33 integer, allocatable :: a(:)
34 allocate(a(10))
35 call sub1(a)
36 end subroutine
38 subroutine sub1(a)
39 integer, intent(out), allocatable :: a(:)
40 end subroutine
42 ! Make sure there is no deallocation of the allocatable intent(out) on the
43 ! caller side.
45 ! CHECK-LABEL: func.func @_QMmod1Psub0()
46 ! CHECK-NOT: fir.freemem
47 ! CHECK: fir.call @_QMmod1Psub1
49 ! Check inline deallocation of allocatable intent(out) on the callee side.
51 ! CHECK-LABEL: func.func @_QMmod1Psub1(
52 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"})
53 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub1Ea"
54 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
55 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
56 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
57 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
58 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
59 ! CHECK: fir.if %[[IS_ALLOCATED]] {
60 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
61 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
62 ! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
63 ! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
64 ! CHECK: %[[C0:.*]] = arith.constant 0 : index
65 ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
66 ! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
67 ! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
68 ! CHECK: }
70 subroutine sub2()
71 integer, allocatable :: a(:)
72 allocate(a(10))
73 call sub3(a)
74 end subroutine
76 ! Check inlined deallocation of allocatble intent(out) on the caller side for BIND(C).
78 ! FIR-LABEL: func.func @_QMmod1Psub2()
79 ! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "a", uniq_name = "_QMmod1Fsub2Ea"}
80 ! FIR: %[[BOX_ALLOC:.*]] = fir.alloca !fir.heap<!fir.array<?xi32>> {uniq_name = "_QMmod1Fsub2Ea.addr"}
81 ! FIR: %[[BOX_ADDR:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
82 ! FIR: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
83 ! FIR: %[[C0:.*]] = arith.constant 0 : i64
84 ! FIR: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
85 ! FIR: fir.if %[[IS_ALLOCATED]] {
86 ! FIR: %[[LOAD:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
87 ! FIR: fir.freemem %[[LOAD]] : !fir.heap<!fir.array<?xi32>>
88 ! FIR: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
89 ! FIR: fir.store %[[ZERO]] to %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
90 ! FIR: }
91 ! FIR: %[[LOAD:.*]] = fir.load %[[BOX_ALLOC]] : !fir.ref<!fir.heap<!fir.array<?xi32>>>
92 ! FIR: %{{.*}} = fir.embox %[[LOAD]](%{{.*}}) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<
93 ! FIR: fir.call @sub3(%[[BOX]]) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> ()
95 ! HLFIR-LABEL: func.func @_QMmod1Psub2(
96 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub2Ea"
97 ! HLFIR: %[[BOX:.*]] = fir.load %[[ARG0]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
98 ! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
99 ! HLFIR: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
100 ! HLFIR: %[[C0:.*]] = arith.constant 0 : i64
101 ! HLFIR: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
102 ! HLFIR: fir.if %[[IS_ALLOCATED]] {
103 ! HLFIR: %[[BOX:.*]] = fir.load %[[ARG0]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
104 ! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
105 ! HLFIR: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
106 ! HLFIR: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
107 ! HLFIR: %[[C0:.*]] = arith.constant 0 : index
108 ! HLFIR: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
109 ! HLFIR: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
110 ! HLFIR: fir.store %[[EMBOX]] to %[[ARG0]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
111 ! HLFIR: fir.call @sub3(%[[ARG0]]#0) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> ()
113 subroutine sub4()
114 type(t1), allocatable :: t
115 call sub5(t)
116 end subroutine
118 subroutine sub5(t)
119 type(t1), allocatable, intent(out) :: t
120 end subroutine
122 ! Make sure there is no deallocation runtime call of the allocatable intent(out)
123 ! on the caller side.
125 ! CHECK-LABEL: func.func @_QMmod1Psub4()
126 ! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>> {bindc_name = "t", uniq_name = "_QMmod1Fsub4Et"}
127 ! HLFIR: %[[BOX:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub4Et"
128 ! CHECK-NOT: fir.call @_FortranAAllocatableDeallocate
129 ! CHECK: fir.call @_QMmod1Psub5(%[[BOX]]{{[#0]*}}) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> ()
131 ! Check deallocation of allocatble intent(out) on the callee side. Deallocation
132 ! is done with a runtime call.
134 ! CHECK-LABEL: func.func @_QMmod1Psub5(
135 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>> {fir.bindc_name = "t"})
136 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub5Et"
137 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>
138 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>) -> !fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>
139 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>) -> i64
140 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
141 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
142 ! CHECK: fir.if %[[IS_ALLOCATED]] {
143 ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#1]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> !fir.ref<!fir.box<none>>
144 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
146 subroutine sub6()
147 type(t1), allocatable :: t
148 call sub7(t)
149 end subroutine
151 ! Check deallocation of allocatble intent(out) on the caller side for BIND(C).
152 ! Deallocation is done with a runtime call.
154 ! CHECK-LABEL: func.func @_QMmod1Psub6()
155 ! FIR: %[[BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>> {bindc_name = "t", uniq_name = "_QMmod1Fsub6Et"}
156 ! HLFIR: %[[BOX:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub6Et"
157 ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOX]]{{[#1]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> !fir.ref<!fir.box<none>>
158 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
159 ! CHECK: fir.call @sub7(%[[BOX]]{{[#0]*}}) {{.*}}: (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMmod1Tt1{{[<]?}}{i:i32}{{[>]?}}>>>>) -> ()
161 subroutine sub8()
162 integer, allocatable :: a(:)
163 allocate(a(10))
164 call sub9(a)
165 end subroutine
167 subroutine sub9(a)
168 integer, intent(out), allocatable, optional :: a(:)
169 end subroutine
171 ! Make sure there is no deallocation of the allocatable intent(out) on the
172 ! caller side.
174 ! CHECK-LABEL: func.func @_QMmod1Psub8()
175 ! CHECK-NOT: fir.freemem
176 ! CHECK: fir.call @_QMmod1Psub9
178 ! Check inline deallocation of optional allocatable intent(out) on the callee side.
180 ! CHECK-LABEL: func.func @_QMmod1Psub9(
181 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a", fir.optional})
182 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub9Ea"
183 ! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]]{{[#1]*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> i1
184 ! CHECK: fir.if %[[IS_PRESENT]] {
185 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
186 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
187 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
188 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
189 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
190 ! CHECK: fir.if %[[IS_ALLOCATED]] {
191 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
192 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
193 ! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
194 ! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
195 ! CHECK: %[[C0:.*]] = arith.constant 0 : index
196 ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
197 ! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
198 ! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
199 ! CHECK: }
200 ! CHECK: }
202 subroutine sub10(a)
203 integer, intent(out), allocatable :: a(:)
205 entry sub11
206 end subroutine
208 ! CHECK-LABEL: func.func @_QMmod1Psub10(
209 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {
210 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub10Ea"
211 ! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
212 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
213 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
214 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
215 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
216 ! CHECK: fir.if %[[IS_ALLOCATED]] {
217 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
218 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
219 ! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
220 ! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
221 ! CHECK: %[[C0:.*]] = arith.constant 0 : index
222 ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
223 ! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
224 ! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
225 ! CHECK: }
227 ! CHECK-LABEL: func.func @_QMmod1Psub11() {
228 ! CHECK-NOT: fir.freemem
230 subroutine sub12(a)
231 integer, intent(out), allocatable :: a(:)
232 entry sub13(a)
233 end subroutine
235 ! CHECK-LABEL: func.func @_QMmod1Psub12(
236 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {
237 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub12Ea"
238 ! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
239 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
240 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
241 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
242 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
243 ! CHECK: fir.if %[[IS_ALLOCATED]] {
244 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
245 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
246 ! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
247 ! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
248 ! CHECK: %[[C0:.*]] = arith.constant 0 : index
249 ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
250 ! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
251 ! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
252 ! CHECK: }
254 ! CHECK-LABEL: func.func @_QMmod1Psub13(
255 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "a"}) {
256 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub12Ea"
257 ! CHECK: %[[LOAD:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
258 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
259 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.array<?xi32>>) -> i64
260 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
261 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
262 ! CHECK: fir.if %[[IS_ALLOCATED]] {
263 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
264 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
265 ! CHECK: fir.freemem %[[BOX_ADDR]] : !fir.heap<!fir.array<?xi32>>
266 ! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
267 ! CHECK: %[[C0:.*]] = arith.constant 0 : index
268 ! CHECK: %[[SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
269 ! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
270 ! CHECK: fir.store %[[EMBOX]] to %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
271 ! CHECK: }
274 subroutine sub14(p)
275 class(t), intent(out), allocatable :: p
276 end subroutine
278 ! CHECK-LABEL: func.func @_QMmod1Psub14(
279 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>> {fir.bindc_name = "p"}) {
280 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub14Ep"
281 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>
282 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>) -> !fir.heap<!fir.type<_QMmod1Tt{a:i32}>>
283 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>) -> i64
284 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
285 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
286 ! CHECK: fir.if %[[IS_ALLOCATED]] {
287 ! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMmod1Tt{a:i32}>
288 ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#1]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
289 ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMmod1Tt{a:i32}>>) -> !fir.ref<none>
290 ! 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
291 ! CHECK: }
293 subroutine sub15(p)
294 class(*), intent(out), allocatable :: p
295 end subroutine
297 ! CHECK-LABEL: func.func @_QMmod1Psub15(
298 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<none>>> {fir.bindc_name = "p"}) {
299 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub15Ep"
300 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.class<!fir.heap<none>>>
301 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<none>>) -> !fir.heap<none>
302 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<none>) -> i64
303 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
304 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
305 ! CHECK: fir.if %[[IS_ALLOCATED]] {
306 ! CHECK: %[[NULL_TYPE_DESC:.*]] = fir.zero_bits !fir.ref<none>
307 ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#1]*}} : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
308 ! 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
309 ! CHECK: }
311 subroutine sub16(p)
312 class(t), optional, intent(out), allocatable :: p
313 end subroutine
315 ! CHECK-LABEL: func.func @_QMmod1Psub16(
316 ! FIR-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>> {fir.bindc_name = "p", fir.optional}) {
317 ! HLFIR: %[[ARG0:.*]]:2 = hlfir.declare {{.*}}"_QMmod1Fsub16Ep"
318 ! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]]{{[#1]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> i1
319 ! CHECK: fir.if %[[IS_PRESENT]] {
320 ! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]{{[#1]*}} : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>
321 ! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>) -> !fir.heap<!fir.type<_QMmod1Tt{a:i32}>>
322 ! CHECK: %[[BOX_ADDR_PTR:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>) -> i64
323 ! CHECK: %[[C0:.*]] = arith.constant 0 : i64
324 ! CHECK: %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_PTR]], %[[C0]] : i64
325 ! CHECK: fir.if %[[IS_ALLOCATED]] {
326 ! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMmod1Tt{a:i32}>
327 ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]]{{[#1]*}} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMmod1Tt{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
328 ! CHECK: %[[TYPE_NONE:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMmod1Tt{a:i32}>>) -> !fir.ref<none>
329 ! 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
330 ! CHECK: }
331 ! CHECK: }
333 end module