1 ; RUN: llc -aarch64-load-store-renaming=true < %s -mtriple=arm64-apple-darwin -mcpu=cyclone -enable-misched=false -frame-pointer=all | FileCheck %s
2 ; RUN: llc -aarch64-load-store-renaming=true < %s -mtriple=arm64-apple-darwin -O0 -frame-pointer=all -fast-isel | FileCheck -check-prefix=FAST %s
5 ; Generated from arm64-arguments.c with -O2.
6 ; Test passing structs with size < 8, < 16 and > 16
7 ; with alignment of 16 and without
9 ; Structs with size < 8
10 %struct.s38 = type { i32, i16 }
11 ; With alignment of 16, the size will be padded to multiple of 16 bytes.
12 %struct.s39 = type { i32, i16, [10 x i8] }
13 ; Structs with size < 16
14 %struct.s40 = type { i32, i16, i32, i16 }
15 %struct.s41 = type { i32, i16, i32, i16 }
16 ; Structs with size > 16
17 %struct.s42 = type { i32, i16, i32, i16, i32, i16 }
18 %struct.s43 = type { i32, i16, i32, i16, i32, i16, [10 x i8] }
20 @g38 = common global %struct.s38 zeroinitializer, align 4
21 @g38_2 = common global %struct.s38 zeroinitializer, align 4
22 @g39 = common global %struct.s39 zeroinitializer, align 16
23 @g39_2 = common global %struct.s39 zeroinitializer, align 16
24 @g40 = common global %struct.s40 zeroinitializer, align 4
25 @g40_2 = common global %struct.s40 zeroinitializer, align 4
26 @g41 = common global %struct.s41 zeroinitializer, align 16
27 @g41_2 = common global %struct.s41 zeroinitializer, align 16
28 @g42 = common global %struct.s42 zeroinitializer, align 4
29 @g42_2 = common global %struct.s42 zeroinitializer, align 4
30 @g43 = common global %struct.s43 zeroinitializer, align 16
31 @g43_2 = common global %struct.s43 zeroinitializer, align 16
33 ; structs with size < 8 bytes, passed via i64 in x1 and x2
34 define i32 @f38(i32 %i, i64 %s1.coerce, i64 %s2.coerce) #0 {
37 ; CHECK: add w[[A:[0-9]+]], w1, w0
38 ; CHECK: add {{w[0-9]+}}, w[[A]], w2
39 %s1.sroa.0.0.extract.trunc = trunc i64 %s1.coerce to i32
40 %s1.sroa.1.4.extract.shift = lshr i64 %s1.coerce, 32
41 %s2.sroa.0.0.extract.trunc = trunc i64 %s2.coerce to i32
42 %s2.sroa.1.4.extract.shift = lshr i64 %s2.coerce, 32
43 %sext8 = shl nuw nsw i64 %s1.sroa.1.4.extract.shift, 16
44 %sext = trunc i64 %sext8 to i32
45 %conv = ashr exact i32 %sext, 16
46 %sext1011 = shl nuw nsw i64 %s2.sroa.1.4.extract.shift, 16
47 %sext10 = trunc i64 %sext1011 to i32
48 %conv6 = ashr exact i32 %sext10, 16
49 %add = add i32 %s1.sroa.0.0.extract.trunc, %i
50 %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
51 %add4 = add i32 %add3, %conv
52 %add7 = add i32 %add4, %conv6
56 define i32 @caller38() #1 {
58 ; CHECK-LABEL: caller38
61 %0 = load i64, ptr @g38, align 4
62 %1 = load i64, ptr @g38_2, align 4
63 %call = tail call i32 @f38(i32 3, i64 %0, i64 %1) #5
67 declare i32 @f38_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
68 i32 %i7, i32 %i8, i32 %i9, i64 %s1.coerce, i64 %s2.coerce) #0
70 ; structs with size < 8 bytes, passed on stack at [sp+8] and [sp+16]
72 define i32 @caller38_stack() #1 {
74 ; CHECK-LABEL: caller38_stack
75 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #8]
76 ; CHECK: mov w[[C:[0-9]+]], #9
77 ; CHECK: str w[[C]], [sp]
78 %0 = load i64, ptr @g38, align 4
79 %1 = load i64, ptr @g38_2, align 4
80 %call = tail call i32 @f38_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
81 i32 7, i32 8, i32 9, i64 %0, i64 %1) #5
85 ; structs with size < 8 bytes, alignment of 16
86 ; passed via i128 in x1 and x3
87 define i32 @f39(i32 %i, i128 %s1.coerce, i128 %s2.coerce) #0 {
90 ; CHECK: add w[[A:[0-9]+]], w1, w0
91 ; CHECK: add {{w[0-9]+}}, w[[A]], w3
92 %s1.sroa.0.0.extract.trunc = trunc i128 %s1.coerce to i32
93 %s1.sroa.1.4.extract.shift = lshr i128 %s1.coerce, 32
94 %s2.sroa.0.0.extract.trunc = trunc i128 %s2.coerce to i32
95 %s2.sroa.1.4.extract.shift = lshr i128 %s2.coerce, 32
96 %sext8 = shl nuw nsw i128 %s1.sroa.1.4.extract.shift, 16
97 %sext = trunc i128 %sext8 to i32
98 %conv = ashr exact i32 %sext, 16
99 %sext1011 = shl nuw nsw i128 %s2.sroa.1.4.extract.shift, 16
100 %sext10 = trunc i128 %sext1011 to i32
101 %conv6 = ashr exact i32 %sext10, 16
102 %add = add i32 %s1.sroa.0.0.extract.trunc, %i
103 %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
104 %add4 = add i32 %add3, %conv
105 %add7 = add i32 %add4, %conv6
109 define i32 @caller39() #1 {
111 ; CHECK-LABEL: caller39
114 %0 = load i128, ptr @g39, align 16
115 %1 = load i128, ptr @g39_2, align 16
116 %call = tail call i32 @f39(i32 3, i128 %0, i128 %1) #5
120 declare i32 @f39_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
121 i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce) #0
123 ; structs with size < 8 bytes, alignment 16
124 ; passed on stack at [sp+16] and [sp+32]
125 define i32 @caller39_stack() #1 {
127 ; CHECK-LABEL: caller39_stack
128 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #32]
129 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
130 ; CHECK: mov w[[C:[0-9]+]], #9
131 ; CHECK: str w[[C]], [sp]
132 %0 = load i128, ptr @g39, align 16
133 %1 = load i128, ptr @g39_2, align 16
134 %call = tail call i32 @f39_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
135 i32 7, i32 8, i32 9, i128 %0, i128 %1) #5
139 ; structs with size < 16 bytes
140 ; passed via i128 in x1 and x3
141 define i32 @f40(i32 %i, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce) #0 {
144 ; CHECK: add w[[A:[0-9]+]], w1, w0
145 ; CHECK: add {{w[0-9]+}}, w[[A]], w3
146 %s1.coerce.fca.0.extract = extractvalue [2 x i64] %s1.coerce, 0
147 %s2.coerce.fca.0.extract = extractvalue [2 x i64] %s2.coerce, 0
148 %s1.sroa.0.0.extract.trunc = trunc i64 %s1.coerce.fca.0.extract to i32
149 %s2.sroa.0.0.extract.trunc = trunc i64 %s2.coerce.fca.0.extract to i32
150 %s1.sroa.0.4.extract.shift = lshr i64 %s1.coerce.fca.0.extract, 32
151 %sext8 = shl nuw nsw i64 %s1.sroa.0.4.extract.shift, 16
152 %sext = trunc i64 %sext8 to i32
153 %conv = ashr exact i32 %sext, 16
154 %s2.sroa.0.4.extract.shift = lshr i64 %s2.coerce.fca.0.extract, 32
155 %sext1011 = shl nuw nsw i64 %s2.sroa.0.4.extract.shift, 16
156 %sext10 = trunc i64 %sext1011 to i32
157 %conv6 = ashr exact i32 %sext10, 16
158 %add = add i32 %s1.sroa.0.0.extract.trunc, %i
159 %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
160 %add4 = add i32 %add3, %conv
161 %add7 = add i32 %add4, %conv6
165 define i32 @caller40() #1 {
167 ; CHECK-LABEL: caller40
170 %0 = load [2 x i64], ptr @g40, align 4
171 %1 = load [2 x i64], ptr @g40_2, align 4
172 %call = tail call i32 @f40(i32 3, [2 x i64] %0, [2 x i64] %1) #5
176 declare i32 @f40_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
177 i32 %i7, i32 %i8, i32 %i9, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce) #0
179 ; structs with size < 16 bytes
180 ; passed on stack at [sp+8] and [sp+24]
181 define i32 @caller40_stack() #1 {
183 ; CHECK-LABEL: caller40_stack
184 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #24]
185 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #8]
186 ; CHECK: mov w[[C:[0-9]+]], #9
187 ; CHECK: str w[[C]], [sp]
188 %0 = load [2 x i64], ptr @g40, align 4
189 %1 = load [2 x i64], ptr @g40_2, align 4
190 %call = tail call i32 @f40_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
191 i32 7, i32 8, i32 9, [2 x i64] %0, [2 x i64] %1) #5
195 ; structs with size < 16 bytes, alignment of 16
196 ; passed via i128 in x1 and x3
197 define i32 @f41(i32 %i, i128 %s1.coerce, i128 %s2.coerce) #0 {
200 ; CHECK: add w[[A:[0-9]+]], w1, w0
201 ; CHECK: add {{w[0-9]+}}, w[[A]], w3
202 %s1.sroa.0.0.extract.trunc = trunc i128 %s1.coerce to i32
203 %s1.sroa.1.4.extract.shift = lshr i128 %s1.coerce, 32
204 %s2.sroa.0.0.extract.trunc = trunc i128 %s2.coerce to i32
205 %s2.sroa.1.4.extract.shift = lshr i128 %s2.coerce, 32
206 %sext8 = shl nuw nsw i128 %s1.sroa.1.4.extract.shift, 16
207 %sext = trunc i128 %sext8 to i32
208 %conv = ashr exact i32 %sext, 16
209 %sext1011 = shl nuw nsw i128 %s2.sroa.1.4.extract.shift, 16
210 %sext10 = trunc i128 %sext1011 to i32
211 %conv6 = ashr exact i32 %sext10, 16
212 %add = add i32 %s1.sroa.0.0.extract.trunc, %i
213 %add3 = add i32 %add, %s2.sroa.0.0.extract.trunc
214 %add4 = add i32 %add3, %conv
215 %add7 = add i32 %add4, %conv6
219 define i32 @caller41() #1 {
221 ; CHECK-LABEL: caller41
224 %0 = load i128, ptr @g41, align 16
225 %1 = load i128, ptr @g41_2, align 16
226 %call = tail call i32 @f41(i32 3, i128 %0, i128 %1) #5
230 declare i32 @f41_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
231 i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce) #0
233 ; structs with size < 16 bytes, alignment of 16
234 ; passed on stack at [sp+16] and [sp+32]
235 define i32 @caller41_stack() #1 {
237 ; CHECK-LABEL: caller41_stack
238 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #32]
239 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
240 ; CHECK: mov w[[C:[0-9]+]], #9
241 ; CHECK: str w[[C]], [sp]
242 %0 = load i128, ptr @g41, align 16
243 %1 = load i128, ptr @g41_2, align 16
244 %call = tail call i32 @f41_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6,
245 i32 7, i32 8, i32 9, i128 %0, i128 %1) #5
249 ; structs with size of 22 bytes, passed indirectly in x1 and x2
250 define i32 @f42(i32 %i, ptr nocapture %s1, ptr nocapture %s2) #2 {
253 ; CHECK: ldr w[[A:[0-9]+]], [x1]
254 ; CHECK: ldr w[[B:[0-9]+]], [x2]
255 ; CHECK: add w[[C:[0-9]+]], w[[A]], w0
256 ; CHECK: add {{w[0-9]+}}, w[[C]], w[[B]]
258 ; FAST: ldr w[[A:[0-9]+]], [x1]
259 ; FAST: ldr w[[B:[0-9]+]], [x2]
260 ; FAST: add w[[C:[0-9]+]], w[[A]], w0
261 ; FAST: add {{w[0-9]+}}, w[[C]], w[[B]]
262 %0 = load i32, ptr %s1, align 4, !tbaa !0
263 %1 = load i32, ptr %s2, align 4, !tbaa !0
264 %s = getelementptr inbounds %struct.s42, ptr %s1, i64 0, i32 1
265 %2 = load i16, ptr %s, align 2, !tbaa !3
266 %conv = sext i16 %2 to i32
267 %s5 = getelementptr inbounds %struct.s42, ptr %s2, i64 0, i32 1
268 %3 = load i16, ptr %s5, align 2, !tbaa !3
269 %conv6 = sext i16 %3 to i32
270 %add = add i32 %0, %i
271 %add3 = add i32 %add, %1
272 %add4 = add i32 %add3, %conv
273 %add7 = add i32 %add4, %conv6
277 ; For s1, we allocate a 22-byte space, pass its address via x1
278 define i32 @caller42() #3 {
280 ; CHECK-LABEL: caller42
281 ; CHECK-DAG: str {{x[0-9]+}}, [sp, #48]
282 ; CHECK-DAG: str {{q[0-9]+}}, [sp, #32]
283 ; CHECK-DAG: str {{x[0-9]+}}, [sp, #16]
284 ; CHECK-DAG: str {{q[0-9]+}}, [sp]
285 ; CHECK: add x1, sp, #32
287 ; Space for s1 is allocated at sp+32
288 ; Space for s2 is allocated at sp
290 ; FAST-LABEL: caller42
291 ; FAST: sub sp, sp, #64
292 ; Space for s1 is allocated at fp-24 = sp+24
293 ; FAST: add x[[A:[0-9]+]], sp, #24
294 ; Call memcpy with size = 24 (0x18)
295 ; FAST: mov {{x[0-9]+}}, #24
296 ; Space for s2 is allocated at sp
297 ; FAST: mov x[[A:[0-9]+]], sp
299 %tmp = alloca %struct.s42, align 4
300 %tmp1 = alloca %struct.s42, align 4
301 call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmp, ptr align 4 @g42, i64 24, i1 false), !tbaa.struct !4
302 call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmp1, ptr align 4 @g42_2, i64 24, i1 false), !tbaa.struct !4
303 %call = call i32 @f42(i32 3, ptr %tmp, ptr %tmp1) #5
307 declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) #4
309 declare i32 @f42_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
310 i32 %i7, i32 %i8, i32 %i9, ptr nocapture %s1,
311 ptr nocapture %s2) #2
313 define i32 @caller42_stack() #3 {
315 ; CHECK-LABEL: caller42_stack
316 ; CHECK: sub sp, sp, #112
317 ; CHECK: add x29, sp, #96
318 ; CHECK-DAG: stur {{x[0-9]+}}, [x29, #-16]
319 ; CHECK-DAG: stur {{q[0-9]+}}, [x29, #-32]
320 ; CHECK-DAG: str {{x[0-9]+}}, [sp, #48]
321 ; CHECK-DAG: str {{q[0-9]+}}, [sp, #32]
322 ; Space for s1 is allocated at x29-32 = sp+64
323 ; Space for s2 is allocated at sp+32
324 ; CHECK: add x[[B:[0-9]+]], sp, #32
325 ; CHECK: str x[[B]], [sp, #16]
326 ; CHECK: sub x[[A:[0-9]+]], x29, #32
327 ; Address of s1 is passed on stack at sp+8
328 ; CHECK: str x[[A]], [sp, #8]
329 ; CHECK: mov w[[C:[0-9]+]], #9
330 ; CHECK: str w[[C]], [sp]
332 ; FAST-LABEL: caller42_stack
333 ; Space for s1 is allocated at fp-24
334 ; FAST: sub x[[A:[0-9]+]], x29, #24
335 ; Call memcpy with size = 24 (0x18)
336 ; FAST: mov {{x[0-9]+}}, #24
338 ; Space for s2 is allocated at sp+32
339 ; FAST: add x[[B:[0-9]+]], sp, #32
342 ; Address of s1 is passed on stack at sp+8
343 ; FAST: str {{w[0-9]+}}, [sp]
344 ; FAST: str {{x[0-9]+}}, [sp, #8]
345 ; FAST: str {{x[0-9]+}}, [sp, #16]
346 %tmp = alloca %struct.s42, align 4
347 %tmp1 = alloca %struct.s42, align 4
348 call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmp, ptr align 4 @g42, i64 24, i1 false), !tbaa.struct !4
349 call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmp1, ptr align 4 @g42_2, i64 24, i1 false), !tbaa.struct !4
350 %call = call i32 @f42_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
351 i32 8, i32 9, ptr %tmp, ptr %tmp1) #5
355 ; structs with size of 22 bytes, alignment of 16
356 ; passed indirectly in x1 and x2
357 define i32 @f43(i32 %i, ptr nocapture %s1, ptr nocapture %s2) #2 {
360 ; CHECK: ldr w[[A:[0-9]+]], [x1]
361 ; CHECK: ldr w[[B:[0-9]+]], [x2]
362 ; CHECK: add w[[C:[0-9]+]], w[[A]], w0
363 ; CHECK: add {{w[0-9]+}}, w[[C]], w[[B]]
365 ; FAST: ldr w[[A:[0-9]+]], [x1]
366 ; FAST: ldr w[[B:[0-9]+]], [x2]
367 ; FAST: add w[[C:[0-9]+]], w[[A]], w0
368 ; FAST: add {{w[0-9]+}}, w[[C]], w[[B]]
369 %0 = load i32, ptr %s1, align 4, !tbaa !0
370 %1 = load i32, ptr %s2, align 4, !tbaa !0
371 %s = getelementptr inbounds %struct.s43, ptr %s1, i64 0, i32 1
372 %2 = load i16, ptr %s, align 2, !tbaa !3
373 %conv = sext i16 %2 to i32
374 %s5 = getelementptr inbounds %struct.s43, ptr %s2, i64 0, i32 1
375 %3 = load i16, ptr %s5, align 2, !tbaa !3
376 %conv6 = sext i16 %3 to i32
377 %add = add i32 %0, %i
378 %add3 = add i32 %add, %1
379 %add4 = add i32 %add3, %conv
380 %add7 = add i32 %add4, %conv6
384 define i32 @caller43() #3 {
386 ; CHECK-LABEL: caller43
387 ; CHECK-DAG: stp q1, q0, [sp, #32]
388 ; CHECK-DAG: stp q1, q0, [sp]
389 ; CHECK: add x1, sp, #32
391 ; Space for s1 is allocated at sp+32
392 ; Space for s2 is allocated at sp
394 ; FAST-LABEL: caller43
395 ; FAST: add x29, sp, #64
396 ; Space for s1 is allocated at sp+32
397 ; Space for s2 is allocated at sp
398 ; FAST: str {{x[0-9]+}}, [sp, #32]
399 ; FAST: str {{x[0-9]+}}, [sp, #40]
400 ; FAST: str {{x[0-9]+}}, [sp, #48]
401 ; FAST: str {{x[0-9]+}}, [sp, #56]
402 ; FAST: str {{x[0-9]+}}, [sp]
403 ; FAST: str {{x[0-9]+}}, [sp, #8]
404 ; FAST: str {{x[0-9]+}}, [sp, #16]
405 ; FAST: str {{x[0-9]+}}, [sp, #24]
406 ; FAST: add x1, sp, #32
408 %tmp = alloca %struct.s43, align 16
409 %tmp1 = alloca %struct.s43, align 16
410 call void @llvm.memcpy.p0.p0.i64(ptr align 16 %tmp, ptr align 16 @g43, i64 32, i1 false), !tbaa.struct !4
411 call void @llvm.memcpy.p0.p0.i64(ptr align 16 %tmp1, ptr align 16 @g43_2, i64 32, i1 false), !tbaa.struct !4
412 %call = call i32 @f43(i32 3, ptr %tmp, ptr %tmp1) #5
416 declare i32 @f43_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6,
417 i32 %i7, i32 %i8, i32 %i9, ptr nocapture %s1,
418 ptr nocapture %s2) #2
420 define i32 @caller43_stack() #3 {
422 ; CHECK-LABEL: caller43_stack
423 ; CHECK: sub sp, sp, #112
424 ; CHECK: add x29, sp, #96
425 ; CHECK-DAG: stp q1, q0, [x29, #-32]
426 ; CHECK-DAG: stp q1, q0, [sp, #32]
427 ; Space for s1 is allocated at x29-32 = sp+64
428 ; Space for s2 is allocated at sp+32
429 ; CHECK: add x[[B:[0-9]+]], sp, #32
430 ; CHECK: str x[[B]], [sp, #16]
431 ; CHECK: sub x[[A:[0-9]+]], x29, #32
432 ; Address of s1 is passed on stack at sp+8
433 ; CHECK: str x[[A]], [sp, #8]
434 ; CHECK: mov w[[C:[0-9]+]], #9
435 ; CHECK: str w[[C]], [sp]
437 ; FAST-LABEL: caller43_stack
438 ; FAST: sub sp, sp, #112
439 ; Space for s1 is allocated at fp-32 = sp+64
440 ; Space for s2 is allocated at sp+32
441 ; FAST: stur {{x[0-9]+}}, [x29, #-32]
442 ; FAST: stur {{x[0-9]+}}, [x29, #-24]
443 ; FAST: stur {{x[0-9]+}}, [x29, #-16]
444 ; FAST: stur {{x[0-9]+}}, [x29, #-8]
445 ; FAST: str {{x[0-9]+}}, [sp, #32]
446 ; FAST: str {{x[0-9]+}}, [sp, #40]
447 ; FAST: str {{x[0-9]+}}, [sp, #48]
448 ; FAST: str {{x[0-9]+}}, [sp, #56]
449 ; Address of s1 is passed on stack at sp+8
450 ; FAST: sub x[[A:[0-9]+]], x29, #32
451 ; FAST: add x[[B:[0-9]+]], sp, #32
452 ; FAST: str {{w[0-9]+}}, [sp]
453 ; FAST: str x[[A]], [sp, #8]
454 ; FAST: str x[[B]], [sp, #16]
455 %tmp = alloca %struct.s43, align 16
456 %tmp1 = alloca %struct.s43, align 16
457 call void @llvm.memcpy.p0.p0.i64(ptr align 16 %tmp, ptr align 16 @g43, i64 32, i1 false), !tbaa.struct !4
458 call void @llvm.memcpy.p0.p0.i64(ptr align 16 %tmp1, ptr align 16 @g43_2, i64 32, i1 false), !tbaa.struct !4
459 %call = call i32 @f43_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7,
460 i32 8, i32 9, ptr %tmp, ptr %tmp1) #5
465 ; Check that we don't split an i128.
466 declare i32 @callee_i128_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5,
467 i32 %i6, i32 %i7, i128 %s1, i32 %i8)
469 define i32 @i128_split() {
471 ; CHECK-LABEL: i128_split
472 ; "i128 %0" should be on stack at [sp].
473 ; "i32 8" should be on stack at [sp, #16].
474 ; CHECK: str {{w[0-9]+}}, [sp, #16]
475 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp]
476 ; FAST-LABEL: i128_split
478 ; FAST: mov x[[ADDR:[0-9]+]], sp
479 ; FAST: str {{w[0-9]+}}, [x[[ADDR]], #16]
480 ; Load/Store opt is disabled with -O0, so the i128 is split.
481 ; FAST: str {{x[0-9]+}}, [x[[ADDR]], #8]
482 ; FAST: str {{x[0-9]+}}, [x[[ADDR]]]
483 %0 = load i128, ptr @g41, align 16
484 %call = tail call i32 @callee_i128_split(i32 1, i32 2, i32 3, i32 4, i32 5,
485 i32 6, i32 7, i128 %0, i32 8) #5
489 declare i32 @callee_i64(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5,
490 i32 %i6, i32 %i7, i64 %s1, i32 %i8)
492 define i32 @i64_split() {
494 ; CHECK-LABEL: i64_split
495 ; "i64 %0" should be in register x7.
496 ; "i32 8" should be on stack at [sp].
497 ; CHECK: ldr x7, [{{x[0-9]+}}]
498 ; CHECK: str {{w[0-9]+}}, [sp]
499 ; FAST-LABEL: i64_split
500 ; FAST: ldr x7, [{{x[0-9]+}}]
501 ; FAST: mov x[[R0:[0-9]+]], sp
502 ; FAST: mov w[[R1:[0-9]+]], #8
503 ; FAST: str w[[R1]], [x[[R0]]]
504 %0 = load i64, ptr @g41, align 16
505 %call = tail call i32 @callee_i64(i32 1, i32 2, i32 3, i32 4, i32 5,
506 i32 6, i32 7, i64 %0, i32 8) #5
510 attributes #0 = { noinline nounwind readnone "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
511 attributes #1 = { nounwind readonly "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
512 attributes #2 = { noinline nounwind readonly "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
513 attributes #3 = { nounwind "fp-contract-model"="standard" "relocation-model"="pic" "ssp-buffers-size"="8" }
514 attributes #4 = { nounwind }
515 attributes #5 = { nobuiltin }
518 !1 = !{!"omnipotent char", !2}
519 !2 = !{!"Simple C/C++ TBAA"}
521 !4 = !{i64 0, i64 4, !0, i64 4, i64 2, !3, i64 8, i64 4, !0, i64 12, i64 2, !3, i64 16, i64 4, !0, i64 20, i64 2, !3}