1// RUN: tco %s | FileCheck %s
2
3// UNSUPPORTED: system-windows
4
5// CHECK-LABEL: define i32* @alloca_scalar_nonchar()
6// CHECK: alloca i32, i64 1
7func.func @alloca_scalar_nonchar() -> !fir.ref<i32> {
8  %1 = fir.alloca i32
9  return %1 : !fir.ref<i32>
10}
11
12// CHECK-LABEL: define i32* @alloca_scalars_nonchar()
13// CHECK: alloca i32, i64 100
14func.func @alloca_scalars_nonchar() -> !fir.ref<i32> {
15  %0 = arith.constant 100 : index
16  %1 = fir.alloca i32, %0
17  return %1 : !fir.ref<i32>
18}
19
20// CHECK-LABEL: define i32* @allocmem_scalar_nonchar(
21// CHECK: call i8* @malloc(i64 4)
22func.func @allocmem_scalar_nonchar() -> !fir.heap<i32> {
23  %1 = fir.allocmem i32
24  return %1 : !fir.heap<i32>
25}
26
27// CHECK-LABEL: define i32* @allocmem_scalars_nonchar(
28// CHECK: call i8* @malloc(i64 400)
29func.func @allocmem_scalars_nonchar() -> !fir.heap<i32> {
30  %0 = arith.constant 100 : index
31  %1 = fir.allocmem i32, %0
32  return %1 : !fir.heap<i32>
33}
34
35// CHECK-LABEL: define [10 x i8]* @alloca_scalar_char(
36// CHECK: alloca [10 x i8], i64 1
37func.func @alloca_scalar_char() -> !fir.ref<!fir.char<1,10>> {
38  %1 = fir.alloca !fir.char<1,10>
39  return %1 : !fir.ref<!fir.char<1,10>>
40}
41
42// CHECK-LABEL: define [10 x i16]* @alloca_scalar_char_kind(
43// CHECK: alloca [10 x i16], i64 1
44func.func @alloca_scalar_char_kind() -> !fir.ref<!fir.char<2,10>> {
45  %1 = fir.alloca !fir.char<2,10>
46  return %1 : !fir.ref<!fir.char<2,10>>
47}
48
49// CHECK-LABEL: define [10 x i8]* @allocmem_scalar_char(
50// CHECK: call i8* @malloc(i64 ptrtoint ([10 x i8]* getelementptr ([10 x i8], [10 x i8]* null, i64 1) to i64))
51func.func @allocmem_scalar_char() -> !fir.heap<!fir.char<1,10>> {
52  %1 = fir.allocmem !fir.char<1,10>
53  return %1 : !fir.heap<!fir.char<1,10>>
54}
55
56// CHECK-LABEL: define [10 x i16]* @allocmem_scalar_char_kind(
57// CHECK: call i8* @malloc(i64 ptrtoint ([10 x i16]* getelementptr ([10 x i16], [10 x i16]* null, i64 1) to i64))
58func.func @allocmem_scalar_char_kind() -> !fir.heap<!fir.char<2,10>> {
59  %1 = fir.allocmem !fir.char<2,10>
60  return %1 : !fir.heap<!fir.char<2,10>>
61}
62
63// CHECK-LABEL: define i8* @alloca_scalar_dynchar(
64// CHECK-SAME: i32 %[[len:.*]])
65// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
66// CHECK: alloca i8, i64 %[[mul1]]
67func.func @alloca_scalar_dynchar(%l : i32) -> !fir.ref<!fir.char<1,?>> {
68  %1 = fir.alloca !fir.char<1,?>(%l : i32)
69  return %1 : !fir.ref<!fir.char<1,?>>
70}
71
72// CHECK-LABEL: define i16* @alloca_scalar_dynchar_kind(
73// CHECK-SAME: i32 %[[len:.*]])
74// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
75// CHECK: alloca i16, i64 %[[mul1]]
76func.func @alloca_scalar_dynchar_kind(%l : i32) -> !fir.ref<!fir.char<2,?>> {
77  %1 = fir.alloca !fir.char<2,?>(%l : i32)
78  return %1 : !fir.ref<!fir.char<2,?>>
79}
80
81// CHECK-LABEL: define i8* @allocmem_scalar_dynchar(
82// CHECK-SAME: i32 %[[len:.*]])
83// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
84// CHECK: %[[mul2:.*]] = mul i64 1, %[[mul1]]
85// CHECK: call i8* @malloc(i64 %[[mul2]])
86func.func @allocmem_scalar_dynchar(%l : i32) -> !fir.heap<!fir.char<1,?>> {
87  %1 = fir.allocmem !fir.char<1,?>(%l : i32)
88  return %1 : !fir.heap<!fir.char<1,?>>
89}
90
91// CHECK-LABEL: define i16* @allocmem_scalar_dynchar_kind(
92// CHECK-SAME: i32 %[[len:.*]])
93// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
94// CHECK: %[[mul2:.*]] = mul i64 2, %[[mul1]]
95// CHECK: call i8* @malloc(i64 %[[mul2]])
96func.func @allocmem_scalar_dynchar_kind(%l : i32) -> !fir.heap<!fir.char<2,?>>{
97  %1 = fir.allocmem !fir.char<2,?>(%l : i32)
98  return %1 : !fir.heap<!fir.char<2,?>>
99}
100
101// CHECK-LABEL: define i32** @alloca_ptr_to_dynarray_nonchar(
102// CHECK: %1 = alloca i32*, i64 1
103func.func @alloca_ptr_to_dynarray_nonchar() -> !fir.ref<!fir.ptr<!fir.array<?xi32>>> {
104  %1 = fir.alloca !fir.ptr<!fir.array<?xi32>>
105  return %1 : !fir.ref<!fir.ptr<!fir.array<?xi32>>>
106}
107
108// CHECK-LABEL: define [3 x [3 x i32]]* @alloca_array_of_nonchar(
109// CHECK: alloca [3 x [3 x i32]], i64 1
110func.func @alloca_array_of_nonchar() -> !fir.ref<!fir.array<3x3xi32>> {
111  %1 = fir.alloca !fir.array<3x3xi32>
112  return %1 : !fir.ref<!fir.array<3x3xi32>>
113}
114
115// CHECK-LABEL: define [3 x [3 x [10 x i8]]]* @alloca_array_of_char(
116// CHECK: alloca [3 x [3 x [10 x i8]]], i64 1
117func.func @alloca_array_of_char() -> !fir.ref<!fir.array<3x3x!fir.char<1,10>>> {
118  %1 = fir.alloca !fir.array<3x3x!fir.char<1,10>>
119  return %1 : !fir.ref<!fir.array<3x3x!fir.char<1,10>>>
120}
121
122// CHECK-LABEL: define i8* @alloca_array_of_dynchar(
123// CHECK-SAME: i32 %[[len:.*]])
124// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
125// CHECK: %[[mul2:.*]] = mul i64 %[[mul1]], 9
126// CHECK: alloca i8, i64 %[[mul2]]
127func.func @alloca_array_of_dynchar(%l: i32) -> !fir.ref<!fir.array<3x3x!fir.char<1,?>>> {
128  %1 = fir.alloca !fir.array<3x3x!fir.char<1,?>>(%l : i32)
129  return %1 : !fir.ref<!fir.array<3x3x!fir.char<1,?>>>
130}
131
132// CHECK-LABEL: define [3 x [3 x i32]]* @allocmem_array_of_nonchar(
133// CHECK: call i8* @malloc(i64 ptrtoint ([3 x [3 x i32]]* getelementptr ([3 x [3 x i32]], [3 x [3 x i32]]* null, i64 1) to i64))
134func.func @allocmem_array_of_nonchar() -> !fir.heap<!fir.array<3x3xi32>> {
135  %1 = fir.allocmem !fir.array<3x3xi32>
136  return %1 : !fir.heap<!fir.array<3x3xi32>>
137}
138
139// CHECK-LABEL: define [3 x [3 x [10 x i8]]]* @allocmem_array_of_char(
140// CHECK: call i8* @malloc(i64 ptrtoint ([3 x [3 x [10 x i8]]]* getelementptr ([3 x [3 x [10 x i8]]], [3 x [3 x [10 x i8]]]* null, i64 1) to i64))
141func.func @allocmem_array_of_char() -> !fir.heap<!fir.array<3x3x!fir.char<1,10>>> {
142  %1 = fir.allocmem !fir.array<3x3x!fir.char<1,10>>
143  return %1 : !fir.heap<!fir.array<3x3x!fir.char<1,10>>>
144}
145
146// CHECK-LABEL: define i8* @allocmem_array_of_dynchar(
147// CHECK-SAME: i32 %[[len:.*]])
148// CHECK: %[[mul1:.*]] = sext i32 %[[len]] to i64
149// CHECK: %[[mul2:.*]] = mul i64 9, %[[mul1]]
150// CHECK: call i8* @malloc(i64 %[[mul2]])
151func.func @allocmem_array_of_dynchar(%l: i32) -> !fir.heap<!fir.array<3x3x!fir.char<1,?>>> {
152  %1 = fir.allocmem !fir.array<3x3x!fir.char<1,?>>(%l : i32)
153  return %1 : !fir.heap<!fir.array<3x3x!fir.char<1,?>>>
154}
155
156// CHECK-LABEL: define [3 x i32]* @alloca_dynarray_of_nonchar(
157// CHECK-SAME: i64 %[[extent:.*]])
158// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
159// CHECK: alloca [3 x i32], i64 %[[prod1]]
160func.func @alloca_dynarray_of_nonchar(%e: index) -> !fir.ref<!fir.array<3x?xi32>> {
161  %1 = fir.alloca !fir.array<3x?xi32>, %e
162  return %1 : !fir.ref<!fir.array<3x?xi32>>
163}
164
165// CHECK-LABEL: define i32* @alloca_dynarray_of_nonchar2(
166// CHECK-SAME: i64 %[[extent:.*]])
167// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
168// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
169// CHECK: alloca i32, i64 %[[prod2]]
170func.func @alloca_dynarray_of_nonchar2(%e: index) -> !fir.ref<!fir.array<?x?xi32>> {
171  %1 = fir.alloca !fir.array<?x?xi32>, %e, %e
172  return %1 : !fir.ref<!fir.array<?x?xi32>>
173}
174
175// CHECK-LABEL: define [3 x i32]* @allocmem_dynarray_of_nonchar(
176// CHECK-SAME: i64 %[[extent:.*]])
177// CHECK: %[[prod1:.*]] = mul i64 ptrtoint ([3 x i32]* getelementptr ([3 x i32], [3 x i32]* null, i64 1) to i64), %[[extent]]
178// CHECK: call i8* @malloc(i64 %[[prod1]])
179func.func @allocmem_dynarray_of_nonchar(%e: index) -> !fir.heap<!fir.array<3x?xi32>> {
180  %1 = fir.allocmem !fir.array<3x?xi32>, %e
181  return %1 : !fir.heap<!fir.array<3x?xi32>>
182}
183
184// CHECK-LABEL: define i32* @allocmem_dynarray_of_nonchar2(
185// CHECK-SAME: i64 %[[extent:.*]])
186// CHECK: %[[prod1:.*]] = mul i64 4, %[[extent]]
187// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
188// CHECK: call i8* @malloc(i64 %[[prod2]])
189func.func @allocmem_dynarray_of_nonchar2(%e: index) -> !fir.heap<!fir.array<?x?xi32>> {
190  %1 = fir.allocmem !fir.array<?x?xi32>, %e, %e
191  return %1 : !fir.heap<!fir.array<?x?xi32>>
192}
193
194// CHECK-LABEL: define [3 x [10 x i16]]* @alloca_dynarray_of_char(
195// CHECK-SAME: i64 %[[extent:.*]])
196// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
197// CHECK: alloca [3 x [10 x i16]], i64 %[[prod1]]
198func.func @alloca_dynarray_of_char(%e : index) -> !fir.ref<!fir.array<3x?x!fir.char<2,10>>> {
199  %1 = fir.alloca !fir.array<3x?x!fir.char<2,10>>, %e
200  return %1 : !fir.ref<!fir.array<3x?x!fir.char<2,10>>>
201}
202
203// CHECK-LABEL: define [10 x i16]* @alloca_dynarray_of_char2(
204// CHECK-SAME: i64 %[[extent:.*]])
205// CHECK: %[[prod1:.*]] = mul i64 1, %[[extent]]
206// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
207// CHECK: alloca [10 x i16], i64 %[[prod2]]
208func.func @alloca_dynarray_of_char2(%e : index) -> !fir.ref<!fir.array<?x?x!fir.char<2,10>>> {
209  %1 = fir.alloca !fir.array<?x?x!fir.char<2,10>>, %e, %e
210  return %1 : !fir.ref<!fir.array<?x?x!fir.char<2,10>>>
211}
212
213// CHECK-LABEL: define [3 x [10 x i16]]* @allocmem_dynarray_of_char(
214// CHECK-SAME: i64 %[[extent:.*]])
215// CHECK: %[[prod1:.*]] = mul i64 ptrtoint ([3 x [10 x i16]]* getelementptr ([3 x [10 x i16]], [3 x [10 x i16]]* null, i64 1) to i64), %[[extent]]
216// CHECK: call i8* @malloc(i64 %[[prod1]])
217func.func @allocmem_dynarray_of_char(%e : index) -> !fir.heap<!fir.array<3x?x!fir.char<2,10>>> {
218  %1 = fir.allocmem !fir.array<3x?x!fir.char<2,10>>, %e
219  return %1 : !fir.heap<!fir.array<3x?x!fir.char<2,10>>>
220}
221
222// CHECK-LABEL: define [10 x i16]* @allocmem_dynarray_of_char2(
223// CHECK-SAME: i64 %[[extent:.*]])
224// CHECK: %[[prod1:.*]] = mul i64 ptrtoint ([10 x i16]* getelementptr ([10 x i16], [10 x i16]* null, i64 1) to i64), %[[extent]]
225// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
226// CHECK: call i8* @malloc(i64 %[[prod2]])
227func.func @allocmem_dynarray_of_char2(%e : index) -> !fir.heap<!fir.array<?x?x!fir.char<2,10>>> {
228  %1 = fir.allocmem !fir.array<?x?x!fir.char<2,10>>, %e, %e
229  return %1 : !fir.heap<!fir.array<?x?x!fir.char<2,10>>>
230}
231
232// CHECK-LABEL: define i16* @alloca_dynarray_of_dynchar(
233// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
234// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64
235// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], 3
236// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
237// CHECK: alloca i16, i64 %[[prod3]]
238func.func @alloca_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.ref<!fir.array<3x?x!fir.char<2,?>>> {
239  %1 = fir.alloca !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e
240  return %1 : !fir.ref<!fir.array<3x?x!fir.char<2,?>>>
241}
242
243// CHECK-LABEL: define i16* @alloca_dynarray_of_dynchar2(
244// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
245// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64
246// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
247// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
248// CHECK: alloca i16, i64 %[[prod3]]
249func.func @alloca_dynarray_of_dynchar2(%l: i32, %e : index) -> !fir.ref<!fir.array<?x?x!fir.char<2,?>>> {
250  %1 = fir.alloca !fir.array<?x?x!fir.char<2,?>>(%l : i32), %e, %e
251  return %1 : !fir.ref<!fir.array<?x?x!fir.char<2,?>>>
252}
253
254// CHECK-LABEL: define i16* @allocmem_dynarray_of_dynchar(
255// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
256// CHECK: %[[prod1:.*]] = sext i32 %[[len]] to i64
257// CHECK: %[[prod2:.*]] = mul i64 6, %[[prod1]]
258// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
259// CHECK: call i8* @malloc(i64 %[[prod3]])
260func.func @allocmem_dynarray_of_dynchar(%l: i32, %e : index) -> !fir.heap<!fir.array<3x?x!fir.char<2,?>>> {
261  %1 = fir.allocmem !fir.array<3x?x!fir.char<2,?>>(%l : i32), %e
262  return %1 : !fir.heap<!fir.array<3x?x!fir.char<2,?>>>
263}
264
265// CHECK-LABEL: define i16* @allocmem_dynarray_of_dynchar2(
266// CHECK-SAME: i32 %[[len:.*]], i64 %[[extent:.*]])
267// CHECK: %[[a:.*]] = sext i32 %[[len]] to i64
268// CHECK: %[[prod1:.*]] = mul i64 2, %[[a]]
269// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[extent]]
270// CHECK: %[[prod3:.*]] = mul i64 %[[prod2]], %[[extent]]
271// CHECK: call i8* @malloc(i64 %[[prod3]])
272func.func @allocmem_dynarray_of_dynchar2(%l: i32, %e : index) -> !fir.heap<!fir.array<?x?x!fir.char<2,?>>> {
273  %1 = fir.allocmem !fir.array<?x?x!fir.char<2,?>>(%l : i32), %e, %e
274  return %1 : !fir.heap<!fir.array<?x?x!fir.char<2,?>>>
275}
276
277// CHECK-LABEL: define i32* @alloca_array_with_holes_nonchar(
278// CHECK-SAME: i64 %[[a:.*]], i64 %[[b:.*]])
279// CHECK: %[[prod1:.*]] = mul i64 60, %[[a]]
280// CHECK: %[[prod2:.*]] = mul i64 %[[prod1]], %[[b]]
281// CHECK: alloca i32, i64 %[[prod2]]
282func.func @alloca_array_with_holes_nonchar(%0 : index, %1 : index) -> !fir.ref<!fir.array<4x?x3x?x5xi32>> {
283  %a = fir.alloca !fir.array<4x?x3x?x5xi32>, %0, %1
284  return %a : !fir.ref<!fir.array<4x?x3x?x5xi32>>
285}
286
287// CHECK-LABEL: define [10 x i16]* @alloca_array_with_holes_char(
288// CHECK-SAME: i64 %[[e:.*]])
289// CHECK: %[[mul:.*]] = mul i64 12, %[[e]]
290// CHECK: alloca [10 x i16], i64 %[[mul]]
291func.func @alloca_array_with_holes_char(%e: index) -> !fir.ref<!fir.array<3x?x4x!fir.char<2,10>>> {
292  %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,10>>, %e
293  return %1 : !fir.ref<!fir.array<3x?x4x!fir.char<2,10>>>
294}
295
296// CHECK-LABEL: define i16* @alloca_array_with_holes_dynchar(
297// CHECK-SAME: i64 %[[len:.*]], i64 %[[extent:.*]])
298// CHECK: %[[a:.*]] = mul i64 %[[len]], 12
299// CHECK: %[[b:.*]] = mul i64 %[[a]], %[[extent]]
300// CHECK: alloca i16, i64 %[[b]]
301func.func @alloca_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir.ref<!fir.array<3x?x4x!fir.char<2,?>>> {
302  %1 = fir.alloca !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1
303  return %1 : !fir.ref<!fir.array<3x?x4x!fir.char<2,?>>>
304}
305
306// CHECK-LABEL: define i32* @allocmem_array_with_holes_nonchar(
307// CHECK-SAME: i64 %[[e1:.*]], i64 %[[e2:.*]])
308// CHECK: %[[a:.*]] = mul i64 240, %[[e1]]
309// CHECK: %[[b:.*]] = mul i64 %3, %[[e2]]
310// CHECK: call i8* @malloc(i64 %[[b]])
311func.func @allocmem_array_with_holes_nonchar(%0 : index, %1 : index) -> !fir.heap<!fir.array<4x?x3x?x5xi32>> {
312  %a = fir.allocmem !fir.array<4x?x3x?x5xi32>, %0, %1
313  return %a : !fir.heap<!fir.array<4x?x3x?x5xi32>>
314}
315
316// CHECK-LABEL: define [10 x i16]* @allocmem_array_with_holes_char(
317// CHECK-SAME: i64 %[[e:.*]])
318// CHECK: %[[mul:.*]] = mul i64 mul (i64 ptrtoint ([10 x i16]* getelementptr ([10 x i16], [10 x i16]* null, i64 1) to i64), i64 12), %[[e]]
319// CHECK: call i8* @malloc(i64 %[[mul]])
320func.func @allocmem_array_with_holes_char(%e: index) -> !fir.heap<!fir.array<3x?x4x!fir.char<2,10>>> {
321  %1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,10>>, %e
322  return %1 : !fir.heap<!fir.array<3x?x4x!fir.char<2,10>>>
323}
324
325// CHECK-LABEL: define i16* @allocmem_array_with_holes_dynchar(
326// CHECK-SAME: i64 %[[len:.*]], i64 %[[extent:.*]])
327// CHECK: %[[a:.*]] = mul i64 24, %[[len]]
328// CHECK: %[[b:.*]] = mul i64 %[[a]], %[[extent]]
329// CHECK: call i8* @malloc(i64 %[[b]])
330func.func @allocmem_array_with_holes_dynchar(%arg0: index, %arg1: index) -> !fir.heap<!fir.array<3x?x4x!fir.char<2,?>>> {
331  %1 = fir.allocmem !fir.array<3x?x4x!fir.char<2,?>>(%arg0 : index), %arg1
332  return %1 : !fir.heap<!fir.array<3x?x4x!fir.char<2,?>>>
333}
334
335