1 ; RUN: llc < %s -march=arm64 -mcpu=cyclone -enable-misched=false | FileCheck %s
2 target triple = "arm64-apple-ios7.0.0"
5 ; Here we have 9 fixed integer arguments the 9th argument in on stack, the
6 ; varargs start right after at 8-byte alignment.
7 define void @fn9(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7, i32 %a8, i32 %a9, ...) nounwind noinline ssp {
10 ; CHECK: ldr {{w[0-9]+}}, [sp, #64]
11 ; CHECK: add [[ARGS:x[0-9]+]], sp, #72
12 ; CHECK: add {{x[0-9]+}}, [[ARGS]], #8
14 ; CHECK: ldr {{w[0-9]+}}, [sp, #72]
15 ; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #8
17 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}]
18 ; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #8
20 ; CHECK: ldr {{w[0-9]+}}, [{{x[0-9]+}}]
21 %1 = alloca i32, align 4
22 %2 = alloca i32, align 4
23 %3 = alloca i32, align 4
24 %4 = alloca i32, align 4
25 %5 = alloca i32, align 4
26 %6 = alloca i32, align 4
27 %7 = alloca i32, align 4
28 %8 = alloca i32, align 4
29 %9 = alloca i32, align 4
30 %args = alloca i8*, align 8
31 %a10 = alloca i32, align 4
32 %a11 = alloca i32, align 4
33 %a12 = alloca i32, align 4
34 store i32 %a1, i32* %1, align 4
35 store i32 %a2, i32* %2, align 4
36 store i32 %a3, i32* %3, align 4
37 store i32 %a4, i32* %4, align 4
38 store i32 %a5, i32* %5, align 4
39 store i32 %a6, i32* %6, align 4
40 store i32 %a7, i32* %7, align 4
41 store i32 %a8, i32* %8, align 4
42 store i32 %a9, i32* %9, align 4
43 %10 = bitcast i8** %args to i8*
44 call void @llvm.va_start(i8* %10)
45 %11 = va_arg i8** %args, i32
46 store i32 %11, i32* %a10, align 4
47 %12 = va_arg i8** %args, i32
48 store i32 %12, i32* %a11, align 4
49 %13 = va_arg i8** %args, i32
50 store i32 %13, i32* %a12, align 4
54 declare void @llvm.va_start(i8*) nounwind
56 define i32 @main() nounwind ssp {
58 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
59 ; CHECK: str {{x[0-9]+}}, [sp, #8]
60 ; CHECK: str {{w[0-9]+}}, [sp]
61 %a1 = alloca i32, align 4
62 %a2 = alloca i32, align 4
63 %a3 = alloca i32, align 4
64 %a4 = alloca i32, align 4
65 %a5 = alloca i32, align 4
66 %a6 = alloca i32, align 4
67 %a7 = alloca i32, align 4
68 %a8 = alloca i32, align 4
69 %a9 = alloca i32, align 4
70 %a10 = alloca i32, align 4
71 %a11 = alloca i32, align 4
72 %a12 = alloca i32, align 4
73 store i32 1, i32* %a1, align 4
74 store i32 2, i32* %a2, align 4
75 store i32 3, i32* %a3, align 4
76 store i32 4, i32* %a4, align 4
77 store i32 5, i32* %a5, align 4
78 store i32 6, i32* %a6, align 4
79 store i32 7, i32* %a7, align 4
80 store i32 8, i32* %a8, align 4
81 store i32 9, i32* %a9, align 4
82 store i32 10, i32* %a10, align 4
83 store i32 11, i32* %a11, align 4
84 store i32 12, i32* %a12, align 4
85 %1 = load i32* %a1, align 4
86 %2 = load i32* %a2, align 4
87 %3 = load i32* %a3, align 4
88 %4 = load i32* %a4, align 4
89 %5 = load i32* %a5, align 4
90 %6 = load i32* %a6, align 4
91 %7 = load i32* %a7, align 4
92 %8 = load i32* %a8, align 4
93 %9 = load i32* %a9, align 4
94 %10 = load i32* %a10, align 4
95 %11 = load i32* %a11, align 4
96 %12 = load i32* %a12, align 4
97 call void (i32, i32, i32, i32, i32, i32, i32, i32, i32, ...)* @fn9(i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i32 %6, i32 %7, i32 %8, i32 %9, i32 %10, i32 %11, i32 %12)
102 @.str = private unnamed_addr constant [4 x i8] c"fmt\00", align 1
103 define void @foo(i8* %fmt, ...) nounwind {
106 ; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, #0x8
107 ; CHECK: ldr {{w[0-9]+}}, [sp, #48]
108 ; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #15
109 ; CHECK: and x[[ADDR:[0-9]+]], {{x[0-9]+}}, #0xfffffffffffffff0
110 ; CHECK: ldr {{q[0-9]+}}, [x[[ADDR]]]
111 %fmt.addr = alloca i8*, align 8
112 %args = alloca i8*, align 8
113 %vc = alloca i32, align 4
114 %vv = alloca <4 x i32>, align 16
115 store i8* %fmt, i8** %fmt.addr, align 8
116 %args1 = bitcast i8** %args to i8*
117 call void @llvm.va_start(i8* %args1)
118 %0 = va_arg i8** %args, i32
119 store i32 %0, i32* %vc, align 4
120 %1 = va_arg i8** %args, <4 x i32>
121 store <4 x i32> %1, <4 x i32>* %vv, align 16
125 define void @bar(i32 %x, <4 x i32> %y) nounwind {
128 ; CHECK: str {{q[0-9]+}}, [sp, #16]
129 ; CHECK: str {{x[0-9]+}}, [sp]
130 %x.addr = alloca i32, align 4
131 %y.addr = alloca <4 x i32>, align 16
132 store i32 %x, i32* %x.addr, align 4
133 store <4 x i32> %y, <4 x i32>* %y.addr, align 16
134 %0 = load i32* %x.addr, align 4
135 %1 = load <4 x i32>* %y.addr, align 16
136 call void (i8*, ...)* @foo(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %0, <4 x i32> %1)
141 ; When passing 16-byte aligned small structs as vararg, make sure the caller
142 ; side is 16-byte aligned on stack.
143 %struct.s41 = type { i32, i16, i32, i16 }
144 define void @foo2(i8* %fmt, ...) nounwind {
147 ; CHECK: orr {{x[0-9]+}}, {{x[0-9]+}}, #0x8
148 ; CHECK: ldr {{w[0-9]+}}, [sp, #48]
149 ; CHECK: add {{x[0-9]+}}, {{x[0-9]+}}, #15
150 ; CHECK: and x[[ADDR:[0-9]+]], {{x[0-9]+}}, #0xfffffffffffffff0
151 ; CHECK: ldr {{q[0-9]+}}, [x[[ADDR]]]
152 %fmt.addr = alloca i8*, align 8
153 %args = alloca i8*, align 8
154 %vc = alloca i32, align 4
155 %vs = alloca %struct.s41, align 16
156 store i8* %fmt, i8** %fmt.addr, align 8
157 %args1 = bitcast i8** %args to i8*
158 call void @llvm.va_start(i8* %args1)
159 %0 = va_arg i8** %args, i32
160 store i32 %0, i32* %vc, align 4
161 %ap.cur = load i8** %args
162 %1 = getelementptr i8* %ap.cur, i32 15
163 %2 = ptrtoint i8* %1 to i64
165 %ap.align = inttoptr i64 %3 to i8*
166 %ap.next = getelementptr i8* %ap.align, i32 16
167 store i8* %ap.next, i8** %args
168 %4 = bitcast i8* %ap.align to %struct.s41*
169 %5 = bitcast %struct.s41* %vs to i8*
170 %6 = bitcast %struct.s41* %4 to i8*
171 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %5, i8* %6, i64 16, i32 16, i1 false)
174 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
176 define void @bar2(i32 %x, i128 %s41.coerce) nounwind {
179 ; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #16]
180 ; CHECK: str {{x[0-9]+}}, [sp]
181 %x.addr = alloca i32, align 4
182 %s41 = alloca %struct.s41, align 16
183 store i32 %x, i32* %x.addr, align 4
184 %0 = bitcast %struct.s41* %s41 to i128*
185 store i128 %s41.coerce, i128* %0, align 1
186 %1 = load i32* %x.addr, align 4
187 %2 = bitcast %struct.s41* %s41 to i128*
188 %3 = load i128* %2, align 1
189 call void (i8*, ...)* @foo2(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %1, i128 %3)