Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Lower / optional-value-caller.f90
blobb4df3415b78253de0a807a885fc84a25aa95f86c
1 ! Test lowering of OPTIONAL VALUE dummy argument on caller side.
2 ! RUN: bbc -emit-fir %s -o - | FileCheck %s
4 ! A copy must be made if the actual is a variable (and no copy-out), but care
5 ! has to be take if the actual argument may be absent at runtime: the copy
6 ! must be conditional. When the allocation is dynamic, the temp allocation and
7 ! deallocation are also conditionals.
9 module test
10 interface
11 subroutine scalar(i)
12 integer, optional, value :: i
13 end subroutine
14 subroutine dyn_char(c)
15 character(*), optional, value :: c
16 end subroutine
17 subroutine array(i)
18 integer, optional, value :: i(100)
19 end subroutine
20 subroutine dyn_array(i, n)
21 integer(8) :: n
22 integer, optional, value :: i(n)
23 end subroutine
24 subroutine dyn_char_array(c, n)
25 integer(8) :: n
26 character(*), optional, value :: c(n)
27 end subroutine
28 function returns_ptr()
29 integer, pointer :: returns_ptr
30 end function
31 end interface
32 contains
34 ! CHECK-LABEL: func @_QMtestPtest_scalar_not_a_var() {
35 subroutine test_scalar_not_a_var()
36 call scalar(42)
37 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {adapt.valuebyref}
38 ! CHECK: %[[VAL_1:.*]] = arith.constant 42 : i32
39 ! CHECK: fir.store %[[VAL_1]] to %[[VAL_0]] : !fir.ref<i32>
40 ! CHECK: fir.call @_QPscalar(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> ()
41 end subroutine
43 ! CHECK-LABEL: func @_QMtestPtest_scalar(
44 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "i", fir.optional}) {
45 subroutine test_scalar(i)
46 integer, optional :: i
47 call scalar(i)
48 ! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref}
49 ! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<i32>) -> i1
50 ! CHECK: %[[VAL_3:.*]] = fir.if %[[VAL_2]] -> (!fir.ref<i32>) {
51 ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
52 ! CHECK: fir.store %[[VAL_4]] to %[[VAL_1]] : !fir.ref<i32>
53 ! CHECK: fir.result %[[VAL_1]] : !fir.ref<i32>
54 ! CHECK: } else {
55 ! CHECK: %[[VAL_5:.*]] = fir.absent !fir.ref<i32>
56 ! CHECK: fir.result %[[VAL_5]] : !fir.ref<i32>
57 ! CHECK: }
58 ! CHECK: fir.call @_QPscalar(%[[VAL_6:.*]]) {{.*}}: (!fir.ref<i32>) -> ()
59 end subroutine
61 ! CHECK-LABEL: func @_QMtestPtest_scalar2(
62 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "i", fir.optional}) {
63 subroutine test_scalar2(i)
64 integer, optional, value :: i
65 call scalar(i)
66 ! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref}
67 ! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<i32>) -> i1
68 ! CHECK: %[[VAL_3:.*]] = fir.if %[[VAL_2]] -> (!fir.ref<i32>) {
69 ! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
70 ! CHECK: fir.store %[[VAL_4]] to %[[VAL_1]] : !fir.ref<i32>
71 ! CHECK: fir.result %[[VAL_1]] : !fir.ref<i32>
72 ! CHECK: } else {
73 ! CHECK: %[[VAL_5:.*]] = fir.absent !fir.ref<i32>
74 ! CHECK: fir.result %[[VAL_5]] : !fir.ref<i32>
75 ! CHECK: }
76 ! CHECK: fir.call @_QPscalar(%[[VAL_6:.*]]) {{.*}}: (!fir.ref<i32>) -> ()
77 end subroutine
79 ! CHECK-LABEL: func @_QMtestPtest_scalar3(
80 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "i", fir.optional}) {
81 subroutine test_scalar3(i)
82 integer, optional :: i
83 ! i must be present when it appears in "()"
84 call scalar((i))
85 ! CHECK: %[[VAL_1:.*]] = fir.alloca i32
86 ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
87 ! CHECK: %[[VAL_3:.*]] = fir.no_reassoc %[[VAL_2]] : i32
88 ! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]] : !fir.ref<i32>
89 ! CHECK: fir.call @_QPscalar(%[[VAL_1]]) {{.*}}: (!fir.ref<i32>) -> ()
90 end subroutine
92 ! CHECK-LABEL: func @_QMtestPtest_scalar_ptr(
93 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "i"}) {
94 subroutine test_scalar_ptr(i)
95 integer, pointer :: i
96 call scalar(i)
97 ! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref}
98 ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
99 ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
100 ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr<i32>) -> i64
101 ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i64
102 ! CHECK: %[[VAL_6:.*]] = arith.cmpi ne, %[[VAL_4]], %[[VAL_5]] : i64
103 ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
104 ! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
105 ! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_6]] -> (!fir.ref<i32>) {
106 ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_8]] : !fir.ptr<i32>
107 ! CHECK: fir.store %[[VAL_10]] to %[[VAL_1]] : !fir.ref<i32>
108 ! CHECK: fir.result %[[VAL_1]] : !fir.ref<i32>
109 ! CHECK: } else {
110 ! CHECK: %[[VAL_11:.*]] = fir.absent !fir.ref<i32>
111 ! CHECK: fir.result %[[VAL_11]] : !fir.ref<i32>
112 ! CHECK: }
113 ! CHECK: fir.call @_QPscalar(%[[VAL_12:.*]]) {{.*}}: (!fir.ref<i32>) -> ()
114 end subroutine
116 ! CHECK-LABEL: func @_QMtestPtest_scalar_simple_var(
117 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "i"}) {
118 subroutine test_scalar_simple_var(i)
119 integer :: i
120 call scalar(i)
121 ! CHECK: %[[VAL_1:.*]] = fir.alloca i32
122 ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
123 ! CHECK: fir.store %[[VAL_2]] to %[[VAL_1]] : !fir.ref<i32>
124 ! CHECK: fir.call @_QPscalar(%[[VAL_1]]) {{.*}}: (!fir.ref<i32>) -> ()
125 end subroutine
128 ! CHECK-LABEL: func @_QMtestPtest_scalar_alloc(
129 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>> {fir.bindc_name = "i"}) {
130 subroutine test_scalar_alloc(i)
131 integer, allocatable :: i
132 call scalar(i)
133 ! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref}
134 ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
135 ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
136 ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.heap<i32>) -> i64
137 ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i64
138 ! CHECK: %[[VAL_6:.*]] = arith.cmpi ne, %[[VAL_4]], %[[VAL_5]] : i64
139 ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
140 ! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
141 ! CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_6]] -> (!fir.ref<i32>) {
142 ! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_8]] : !fir.heap<i32>
143 ! CHECK: fir.store %[[VAL_10]] to %[[VAL_1]] : !fir.ref<i32>
144 ! CHECK: fir.result %[[VAL_1]] : !fir.ref<i32>
145 ! CHECK: } else {
146 ! CHECK: %[[VAL_11:.*]] = fir.absent !fir.ref<i32>
147 ! CHECK: fir.result %[[VAL_11]] : !fir.ref<i32>
148 ! CHECK: }
149 ! CHECK: fir.call @_QPscalar(%[[VAL_12:.*]]) {{.*}}: (!fir.ref<i32>) -> ()
150 end subroutine
152 ! CHECK-LABEL: func @_QMtestPtest_ptr_2() {
153 subroutine test_ptr_2()
154 call scalar(returns_ptr())
155 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {adapt.valuebyref}
156 ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> {bindc_name = ".result"}
157 ! CHECK: %[[VAL_2:.*]] = fir.call @_QPreturns_ptr() {{.*}}: () -> !fir.box<!fir.ptr<i32>>
158 ! CHECK: fir.save_result %[[VAL_2]] to %[[VAL_1]] : !fir.box<!fir.ptr<i32>>, !fir.ref<!fir.box<!fir.ptr<i32>>>
159 ! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
160 ! CHECK: %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
161 ! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ptr<i32>) -> i64
162 ! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64
163 ! CHECK: %[[VAL_7:.*]] = arith.cmpi ne, %[[VAL_5]], %[[VAL_6]] : i64
164 ! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
165 ! CHECK: %[[VAL_9:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
166 ! CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_7]] -> (!fir.ref<i32>) {
167 ! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ptr<i32>
168 ! CHECK: fir.store %[[VAL_11]] to %[[VAL_0]] : !fir.ref<i32>
169 ! CHECK: fir.result %[[VAL_0]] : !fir.ref<i32>
170 ! CHECK: } else {
171 ! CHECK: %[[VAL_12:.*]] = fir.absent !fir.ref<i32>
172 ! CHECK: fir.result %[[VAL_12]] : !fir.ref<i32>
173 ! CHECK: }
174 ! CHECK: fir.call @_QPscalar(%[[VAL_13:.*]]) {{.*}}: (!fir.ref<i32>) -> ()
175 end subroutine
177 ! CHECK-LABEL: func @_QMtestPtest_array(
178 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "i", fir.optional}) {
179 subroutine test_array(i)
180 integer, optional :: i(100)
181 call array(i)
182 ! CHECK: %[[VAL_1:.*]] = arith.constant 100 : index
183 ! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<!fir.array<100xi32>>) -> i1
184 ! CHECK: %[[VAL_3:.*]] = fir.if %[[VAL_2]] -> (!fir.heap<!fir.array<100xi32>>) {
185 ! CHECK: %[[VAL_4:.*]] = fir.allocmem !fir.array<100xi32>, %[[VAL_1]] {uniq_name = ".copy"}
186 ! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
187 ! CHECK: %[[VAL_6:.*]] = fir.array_load %[[VAL_4]](%[[VAL_5]]) : (!fir.heap<!fir.array<100xi32>>, !fir.shape<1>) -> !fir.array<100xi32>
188 ! CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
189 ! CHECK: %[[VAL_8:.*]] = fir.array_load %[[VAL_0]](%[[VAL_7]]) : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> !fir.array<100xi32>
190 ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index
191 ! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index
192 ! CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_1]], %[[VAL_9]] : index
193 ! CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_10]] to %[[VAL_11]] step %[[VAL_9]] unordered iter_args(%[[VAL_14:.*]] = %[[VAL_6]]) -> (!fir.array<100xi32>) {
194 ! CHECK: %[[VAL_15:.*]] = fir.array_fetch %[[VAL_8]], %[[VAL_13]] : (!fir.array<100xi32>, index) -> i32
195 ! CHECK: %[[VAL_16:.*]] = fir.array_update %[[VAL_14]], %[[VAL_15]], %[[VAL_13]] : (!fir.array<100xi32>, i32, index) -> !fir.array<100xi32>
196 ! CHECK: fir.result %[[VAL_16]] : !fir.array<100xi32>
197 ! CHECK: }
198 ! CHECK: fir.array_merge_store %[[VAL_6]], %[[VAL_17:.*]] to %[[VAL_4]] : !fir.array<100xi32>, !fir.array<100xi32>, !fir.heap<!fir.array<100xi32>>
199 ! CHECK: fir.result %[[VAL_4]] : !fir.heap<!fir.array<100xi32>>
200 ! CHECK: } else {
201 ! CHECK: %[[VAL_18:.*]] = fir.zero_bits !fir.heap<!fir.array<100xi32>>
202 ! CHECK: fir.result %[[VAL_18]] : !fir.heap<!fir.array<100xi32>>
203 ! CHECK: }
204 ! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_20:.*]] : (!fir.heap<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>>
205 ! CHECK: fir.call @_QParray(%[[VAL_19]]) {{.*}}: (!fir.ref<!fir.array<100xi32>>) -> ()
206 ! CHECK: fir.if %[[VAL_2]] {
207 ! CHECK: fir.freemem %[[VAL_20]] : !fir.heap<!fir.array<100xi32>>
208 ! CHECK: }
209 end subroutine
211 ! CHECK-LABEL: func @_QMtestPtest_array2(
212 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "i", fir.optional},
213 subroutine test_array2(i, n)
214 integer(8) :: n
215 integer, optional, value :: i(n)
216 call array(i)
217 ! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i64> {fir.bindc_name = "n"}) {
218 ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]] : !fir.ref<i64>
219 ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i64) -> index
220 ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
221 ! CHECK: %[[VAL_5:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[VAL_4]] : index
222 ! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_5]], %[[VAL_3]], %[[VAL_4]] : index
223 ! CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<!fir.array<?xi32>>) -> i1
224 ! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.heap<!fir.array<?xi32>>) {
225 ! CHECK: %[[VAL_9:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_6]] {uniq_name = ".copy"}
226 ! CHECK: %[[VAL_17:.*]] = fir.do_loop
227 ! CHECK: }
228 ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_17]] to %[[VAL_9]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.heap<!fir.array<?xi32>>
229 ! CHECK: fir.result %[[VAL_9]] : !fir.heap<!fir.array<?xi32>>
230 ! CHECK: } else {
231 ! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
232 ! CHECK: fir.result %[[VAL_23]] : !fir.heap<!fir.array<?xi32>>
233 ! CHECK: }
234 ! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_8]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<100xi32>>
235 ! CHECK: fir.call @_QParray(%[[VAL_24]]) {{.*}}: (!fir.ref<!fir.array<100xi32>>) -> ()
236 ! CHECK: fir.if %[[VAL_7]] {
237 ! CHECK: fir.freemem %[[VAL_8]] : !fir.heap<!fir.array<?xi32>>
238 ! CHECK: }
239 end subroutine
241 ! CHECK-LABEL: func @_QMtestPtest_dyn_array(
242 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "i", fir.optional},
243 ! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i64> {fir.bindc_name = "n"}) {
244 subroutine test_dyn_array(i, n)
245 integer(8) :: n
246 integer, optional :: i(n)
247 call dyn_array(i, n)
248 ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]] : !fir.ref<i64>
249 ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i64) -> index
250 ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
251 ! CHECK: %[[VAL_5:.*]] = arith.cmpi sgt, %[[VAL_3]], %[[VAL_4]] : index
252 ! CHECK: %[[VAL_6:.*]] = arith.select %[[VAL_5]], %[[VAL_3]], %[[VAL_4]] : index
253 ! CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<!fir.array<?xi32>>) -> i1
254 ! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.heap<!fir.array<?xi32>>) {
255 ! CHECK: %[[VAL_9:.*]] = fir.allocmem !fir.array<?xi32>, %{{.*}} {uniq_name = ".copy"}
256 ! CHECK: %[[VAL_17:.*]] = fir.do_loop
257 ! CHECK: }
258 ! CHECK: fir.array_merge_store %{{.*}}, %[[VAL_17]] to %[[VAL_9]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.heap<!fir.array<?xi32>>
259 ! CHECK: fir.result %[[VAL_9]] : !fir.heap<!fir.array<?xi32>>
260 ! CHECK: } else {
261 ! CHECK: %[[VAL_23:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
262 ! CHECK: fir.result %[[VAL_23]] : !fir.heap<!fir.array<?xi32>>
263 ! CHECK: }
264 ! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_8]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
265 ! CHECK: fir.call @_QPdyn_array(%[[VAL_24]], %[[VAL_1]]) {{.*}}: (!fir.ref<!fir.array<?xi32>>, !fir.ref<i64>) -> ()
266 ! CHECK: fir.if %[[VAL_7]] {
267 ! CHECK: fir.freemem %[[VAL_8]] : !fir.heap<!fir.array<?xi32>>
268 ! CHECK: }
269 end subroutine
271 ! CHECK-LABEL: func @_QMtestPtest_dyn_array_from_assumed(
272 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "i", fir.optional},
273 ! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i64> {fir.bindc_name = "n"}) {
274 subroutine test_dyn_array_from_assumed(i, n)
275 integer(8) :: n
276 integer, optional :: i(:)
277 call dyn_array(i, n)
278 ! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?xi32>>) -> i1
279 ! CHECK: %[[VAL_3:.*]] = fir.zero_bits !fir.ref<!fir.array<?xi32>>
280 ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
281 ! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
282 ! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_3]](%[[VAL_5]]) : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
283 ! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_2]], %[[VAL_0]], %[[VAL_6]] : !fir.box<!fir.array<?xi32>>
284 ! CHECK: %[[box_none:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
285 ! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
286 ! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_2]] -> (!fir.heap<!fir.array<?xi32>>) {
287 ! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
288 ! CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_7]], %[[VAL_9]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
289 ! CHECK: %[[VAL_11:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_10]]#1 {uniq_name = ".copy"}
290 ! CHECK: fir.call @_FortranAAssign
291 ! CHECK: fir.result %[[VAL_11]] : !fir.heap<!fir.array<?xi32>>
292 ! CHECK: } else {
293 ! CHECK: %[[VAL_24:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
294 ! CHECK: fir.result %[[VAL_24]] : !fir.heap<!fir.array<?xi32>>
295 ! CHECK: }
296 ! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1
297 ! CHECK: %[[and:.*]] = arith.andi %[[VAL_2]], %[[not_contiguous]] : i1
298 ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_8]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
299 ! CHECK: fir.call @_QPdyn_array(%[[VAL_25]], %[[VAL_1]]) {{.*}}: (!fir.ref<!fir.array<?xi32>>, !fir.ref<i64>) -> ()
300 ! CHECK: fir.if %[[and]] {
301 ! CHECK-NOT: fir.call @_FortranAAssign
302 ! CHECK: fir.freemem %[[VAL_8]] : !fir.heap<!fir.array<?xi32>>
303 ! CHECK: }
304 end subroutine
306 ! CHECK-LABEL: func @_QMtestPtest_array_ptr(
307 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "i"}) {
308 subroutine test_array_ptr(i)
309 integer, pointer :: i(:)
310 call array(i)
311 ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.array<?xi32>>
312 ! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
313 ! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
314 ! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ptr<!fir.array<?xi32>>) -> i64
315 ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i64
316 ! CHECK: %[[VAL_6:.*]] = arith.cmpi ne, %[[VAL_4]], %[[VAL_5]] : i64
317 ! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
318 ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.box<none>
319 ! CHECK: %[[VAL_9:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_8]]) fastmath<contract> : (!fir.box<none>) -> i1
320 ! CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_6]] -> (!fir.heap<!fir.array<?xi32>>) {
321 ! CHECK: %[[VAL_11:.*]] = fir.if %[[VAL_9]] -> (!fir.heap<!fir.array<?xi32>>) {
322 ! CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
323 ! CHECK: fir.result %[[VAL_12]] : !fir.heap<!fir.array<?xi32>>
324 ! CHECK: } else {
325 ! CHECK: %[[VAL_13:.*]] = arith.constant 0 : index
326 ! CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_7]], %[[VAL_13]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
327 ! CHECK: %[[VAL_15:.*]] = fir.allocmem !fir.array<?xi32>, %[[VAL_14]]#1 {uniq_name = ".copy"}
328 ! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]]#1 : (index) -> !fir.shape<1>
329 ! CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_15]](%[[VAL_16]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
330 ! CHECK: fir.store %[[VAL_17]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
331 ! CHECK: %[[VAL_18:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
332 ! CHECK: %[[VAL_19:.*]] = arith.constant {{.*}} : i32
333 ! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<none>>
334 ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.box<none>
335 ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_18]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
336 ! CHECK: %[[VAL_23:.*]] = fir.call @_FortranAAssign(%[[VAL_20]], %[[VAL_21]], %[[VAL_22]], %[[VAL_19]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
337 ! CHECK: fir.result %[[VAL_15]] : !fir.heap<!fir.array<?xi32>>
338 ! CHECK: }
339 ! CHECK: fir.result %[[VAL_24:.*]] : !fir.heap<!fir.array<?xi32>>
340 ! CHECK: } else {
341 ! CHECK: %[[VAL_25:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
342 ! CHECK: fir.result %[[VAL_25]] : !fir.heap<!fir.array<?xi32>>
343 ! CHECK: }
344 ! CHECK: %[[VAL_26:.*]] = arith.constant false
345 ! CHECK: %[[VAL_27:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_26]] : i1
346 ! CHECK: %[[VAL_28:.*]] = arith.andi %[[VAL_6]], %[[VAL_27]] : i1
347 ! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_30:.*]] : (!fir.heap<!fir.array<?xi32>>) -> !fir.ref<!fir.array<100xi32>>
348 ! CHECK: fir.call @_QParray(%[[VAL_29]]) fastmath<contract> : (!fir.ref<!fir.array<100xi32>>) -> ()
349 ! CHECK: fir.if %[[VAL_28]] {
350 ! CHECK: fir.freemem %[[VAL_30]] : !fir.heap<!fir.array<?xi32>>
351 ! CHECK: }
352 ! CHECK: return
353 ! CHECK: }
354 end subroutine
356 ! CHECK-LABEL: func @_QMtestPtest_char(
357 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1> {fir.bindc_name = "c", fir.optional}) {
358 subroutine test_char(c)
359 character(*), optional :: c
360 call dyn_char(c)
361 ! CHECK: %[[VAL_1:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
362 ! CHECK: %[[VAL_2:.*]] = fir.is_present %[[VAL_1]]#0 : (!fir.ref<!fir.char<1,?>>) -> i1
363 ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
364 ! CHECK: %[[VAL_4:.*]] = arith.select %[[VAL_2]], %[[VAL_1]]#1, %[[VAL_3]] : index
365 ! CHECK: %[[VAL_5:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_4]] : index) {adapt.valuebyref}
366 ! CHECK: %[[VAL_6:.*]] = fir.if %[[VAL_2]] -> (!fir.ref<!fir.char<1,?>>) {
367 ! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
368 ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_1]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
369 ! CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_13]], %[[VAL_14]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
370 ! CHECK: fir.result %[[VAL_5]] : !fir.ref<!fir.char<1,?>>
371 ! CHECK: } else {
372 ! CHECK: %[[VAL_24:.*]] = fir.absent !fir.ref<!fir.char<1,?>>
373 ! CHECK: fir.result %[[VAL_24]] : !fir.ref<!fir.char<1,?>>
374 ! CHECK: }
375 ! CHECK: %[[VAL_25:.*]] = fir.emboxchar %[[VAL_6]], %[[VAL_4]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
376 ! CHECK: fir.call @_QPdyn_char(%[[VAL_25]]) {{.*}}: (!fir.boxchar<1>) -> ()
377 end subroutine
379 ! CHECK-LABEL: func @_QMtestPtest_char_ptr(
380 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>> {fir.bindc_name = "c"}) {
381 subroutine test_char_ptr(c)
382 character(:), pointer :: c
383 call dyn_char(c)
384 ! CHECK: %[[VAL_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>
385 ! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.ptr<!fir.char<1,?>>>) -> !fir.ptr<!fir.char<1,?>>
386 ! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (!fir.ptr<!fir.char<1,?>>) -> i64
387 ! CHECK: %[[VAL_4:.*]] = arith.constant 0 : i64
388 ! CHECK: %[[VAL_5:.*]] = arith.cmpi ne, %[[VAL_3]], %[[VAL_4]] : i64
389 ! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>
390 ! CHECK: %[[VAL_7:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box<!fir.ptr<!fir.char<1,?>>>) -> index
391 ! CHECK: %[[VAL_8:.*]] = fir.box_addr %[[VAL_6]] : (!fir.box<!fir.ptr<!fir.char<1,?>>>) -> !fir.ptr<!fir.char<1,?>>
392 ! CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
393 ! CHECK: %[[VAL_10:.*]] = arith.select %[[VAL_5]], %[[VAL_7]], %[[VAL_9]] : index
394 ! CHECK: %[[VAL_11:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_10]] : index) {adapt.valuebyref}
395 ! CHECK: %[[VAL_12:.*]] = fir.if %[[VAL_5]] -> (!fir.ref<!fir.char<1,?>>) {
396 ! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
397 ! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_8]] : (!fir.ptr<!fir.char<1,?>>) -> !fir.ref<i8>
398 ! CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_19]], %[[VAL_20]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
399 ! CHECK: fir.result %[[VAL_11]] : !fir.ref<!fir.char<1,?>>
400 ! CHECK: } else {
401 ! CHECK: %[[VAL_30:.*]] = fir.absent !fir.ref<!fir.char<1,?>>
402 ! CHECK: fir.result %[[VAL_30]] : !fir.ref<!fir.char<1,?>>
403 ! CHECK: }
404 ! CHECK: %[[VAL_31:.*]] = fir.emboxchar %[[VAL_12]], %[[VAL_10]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
405 ! CHECK: fir.call @_QPdyn_char(%[[VAL_31]]) {{.*}}: (!fir.boxchar<1>) -> ()
406 end subroutine
408 ! CHECK-LABEL: func @_QMtestPtest_char_array(
409 ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>> {fir.bindc_name = "c", fir.optional}) {
410 subroutine test_char_array(c)
411 integer(8) :: n
412 character(*), optional :: c(:)
413 call dyn_char_array(c, n)
414 ! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.array<?x!fir.char<1,?>>>
415 ! CHECK: %[[VAL_2:.*]] = fir.alloca i64 {bindc_name = "n", uniq_name = "_QMtestFtest_char_arrayEn"}
416 ! CHECK: %[[VAL_3:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> i1
417 ! CHECK: %[[VAL_4:.*]] = fir.zero_bits !fir.ref<!fir.array<?x!fir.char<1,?>>>
418 ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
419 ! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
420 ! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index
421 ! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_4]](%[[VAL_6]]) typeparams %[[VAL_7]] : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
422 ! CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_3]], %[[VAL_0]], %[[VAL_8]] : !fir.box<!fir.array<?x!fir.char<1,?>>>
423 ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.box<none>
424 ! CHECK: %[[VAL_11:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_10]]) fastmath<contract> : (!fir.box<none>) -> i1
425 ! CHECK: %[[VAL_12:.*]] = fir.if %[[VAL_3]] -> (!fir.heap<!fir.array<?x!fir.char<1,?>>>) {
426 ! CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_11]] -> (!fir.heap<!fir.array<?x!fir.char<1,?>>>) {
427 ! CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x!fir.char<1,?>>>
428 ! CHECK: fir.result %[[VAL_14]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
429 ! CHECK: } else {
430 ! CHECK: %[[VAL_15:.*]] = arith.constant 0 : index
431 ! CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_9]], %[[VAL_15]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index) -> (index, index, index)
432 ! CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_9]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
433 ! CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<?x!fir.char<1,?>>(%[[VAL_17]] : index), %[[VAL_16]]#1 {uniq_name = ".copy"}
434 ! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_16]]#1 : (index) -> !fir.shape<1>
435 ! CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_18]](%[[VAL_19]]) typeparams %[[VAL_17]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
436 ! CHECK: fir.store %[[VAL_20]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?x!fir.char<1,?>>>>
437 ! CHECK: %[[VAL_21:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
438 ! CHECK: %[[VAL_22:.*]] = arith.constant {{.*}} : i32
439 ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.array<?x!fir.char<1,?>>>>) -> !fir.ref<!fir.box<none>>
440 ! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.box<none>
441 ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
442 ! CHECK: %[[VAL_26:.*]] = fir.call @_FortranAAssign(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_22]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
443 ! CHECK: fir.result %[[VAL_18]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
444 ! CHECK: }
445 ! CHECK: fir.result %[[VAL_27:.*]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
446 ! CHECK: } else {
447 ! CHECK: %[[VAL_28:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.char<1,?>>>
448 ! CHECK: fir.result %[[VAL_28]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
449 ! CHECK: }
450 ! CHECK: %[[VAL_29:.*]] = fir.box_elesize %[[VAL_9]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
451 ! CHECK: %[[VAL_30:.*]] = arith.constant false
452 ! CHECK: %[[VAL_31:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_30]] : i1
453 ! CHECK: %[[VAL_32:.*]] = arith.andi %[[VAL_3]], %[[VAL_31]] : i1
454 ! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_34:.*]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.char<1,?>>
455 ! CHECK: %[[VAL_35:.*]] = fir.emboxchar %[[VAL_33]], %[[VAL_29]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
456 ! CHECK: fir.call @_QPdyn_char_array(%[[VAL_35]], %[[VAL_2]]) fastmath<contract> : (!fir.boxchar<1>, !fir.ref<i64>) -> ()
457 ! CHECK: fir.if %[[VAL_32]] {
458 ! CHECK: fir.freemem %[[VAL_34]] : !fir.heap<!fir.array<?x!fir.char<1,?>>>
459 ! CHECK: }
460 ! CHECK: return
461 ! CHECK: }
462 end subroutine