[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / win64_vararg.ll
blobd9bb2ff6b1240ea24d44c5f6d0d1585ae6873e29
1 ; RUN: llc < %s -mtriple=aarch64-pc-win32 | FileCheck %s
3 define void @pass_va(i32 %count, ...) nounwind {
4 entry:
5 ; CHECK: str     x30, [sp, #-80]!
6 ; CHECK: add     x8, sp, #24
7 ; CHECK: add     x0, sp, #24
8 ; CHECK: stp     x1, x2, [sp, #24]
9 ; CHECK: stp     x3, x4, [sp, #40]
10 ; CHECK: stp     x5, x6, [sp, #56]
11 ; CHECK: str     x7, [sp, #72]
12 ; CHECK: str     x8, [sp, #8]
13 ; CHECK: bl      other_func
14 ; CHECK: ldr     x30, [sp], #80
15 ; CHECK: ret
16   %ap = alloca i8*, align 8
17   %ap1 = bitcast i8** %ap to i8*
18   call void @llvm.va_start(i8* %ap1)
19   %ap2 = load i8*, i8** %ap, align 8
20   call void @other_func(i8* %ap2)
21   ret void
24 declare void @other_func(i8*) local_unnamed_addr
26 declare void @llvm.va_start(i8*) nounwind
27 declare void @llvm.va_copy(i8*, i8*) nounwind
29 ; CHECK-LABEL: f9:
30 ; CHECK: sub     sp, sp, #16
31 ; CHECK: add     x8, sp, #24
32 ; CHECK: add     x0, sp, #24
33 ; CHECK: str     x8, [sp, #8]
34 ; CHECK: add     sp, sp, #16
35 ; CHECK: ret
36 define i8* @f9(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, ...) nounwind {
37 entry:
38   %ap = alloca i8*, align 8
39   %ap1 = bitcast i8** %ap to i8*
40   call void @llvm.va_start(i8* %ap1)
41   %ap2 = load i8*, i8** %ap, align 8
42   ret i8* %ap2
45 ; CHECK-LABEL: f8:
46 ; CHECK: sub     sp, sp, #16
47 ; CHECK: add     x8, sp, #16
48 ; CHECK: add     x0, sp, #16
49 ; CHECK: str     x8, [sp, #8]
50 ; CHECK: add     sp, sp, #16
51 ; CHECK: ret
52 define i8* @f8(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, ...) nounwind {
53 entry:
54   %ap = alloca i8*, align 8
55   %ap1 = bitcast i8** %ap to i8*
56   call void @llvm.va_start(i8* %ap1)
57   %ap2 = load i8*, i8** %ap, align 8
58   ret i8* %ap2
61 ; CHECK-LABEL: f7:
62 ; CHECK: sub     sp, sp, #32
63 ; CHECK: add     x8, sp, #24
64 ; CHECK: str     x7, [sp, #24]
65 ; CHECK: add     x0, sp, #24
66 ; CHECK: str     x8, [sp, #8]
67 ; CHECK: add     sp, sp, #32
68 ; CHECK: ret
69 define i8* @f7(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, ...) nounwind {
70 entry:
71   %ap = alloca i8*, align 8
72   %ap1 = bitcast i8** %ap to i8*
73   call void @llvm.va_start(i8* %ap1)
74   %ap2 = load i8*, i8** %ap, align 8
75   ret i8* %ap2
78 ; CHECK-LABEL: copy1:
79 ; CHECK: sub     sp, sp, #80
80 ; CHECK: add     x8, sp, #24
81 ; CHECK: stp     x1, x2, [sp, #24]
82 ; CHECK: stp     x3, x4, [sp, #40]
83 ; CHECK: stp     x5, x6, [sp, #56]
84 ; CHECK: str     x7, [sp, #72]
85 ; CHECK: stp     x8, x8, [sp], #80
86 ; CHECK: ret
87 define void @copy1(i64 %a0, ...) nounwind {
88 entry:
89   %ap = alloca i8*, align 8
90   %cp = alloca i8*, align 8
91   %ap1 = bitcast i8** %ap to i8*
92   %cp1 = bitcast i8** %cp to i8*
93   call void @llvm.va_start(i8* %ap1)
94   call void @llvm.va_copy(i8* %cp1, i8* %ap1)
95   ret void
98 declare void @llvm.va_end(i8*)
99 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
100 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
102 declare i32 @__stdio_common_vsprintf(i64, i8*, i64, i8*, i8*, i8*) local_unnamed_addr #3
103 declare i64* @__local_stdio_printf_options() local_unnamed_addr #4
105 ; CHECK-LABEL: fp
106 ; CHECK: str     x21, [sp, #-96]!
107 ; CHECK: stp     x19, x20, [sp, #16]
108 ; CHECK: stp     x29, x30, [sp, #32]
109 ; CHECK: add     x29, sp, #32
110 ; CHECK: add     x8, x29, #24
111 ; CHECK: mov     x19, x2
112 ; CHECK: mov     x20, x1
113 ; CHECK: mov     x21, x0
114 ; CHECK: stp     x3, x4, [x29, #24]
115 ; CHECK: stp     x5, x6, [x29, #40]
116 ; CHECK: str     x7, [x29, #56]
117 ; CHECK: str     x8, [sp, #8]
118 ; CHECK: bl      __local_stdio_printf_options
119 ; CHECK: ldr     x8, [x0]
120 ; CHECK: add     x5, x29, #24
121 ; CHECK: mov     x1, x21
122 ; CHECK: mov     x2, x20
123 ; CHECK: orr     x0, x8, #0x2
124 ; CHECK: mov     x3, x19
125 ; CHECK: mov     x4, xzr
126 ; CHECK: bl      __stdio_common_vsprintf
127 ; CHECK: cmp     w0, #0
128 ; CHECK: csinv   w0, w0, wzr, ge
129 ; CHECK: ldp     x29, x30, [sp, #32]
130 ; CHECK: ldp     x19, x20, [sp, #16]
131 ; CHECK: ldr     x21, [sp], #96
132 ; CHECK: ret
133 define i32 @fp(i8*, i64, i8*, ...) local_unnamed_addr #6 {
134   %4 = alloca i8*, align 8
135   %5 = bitcast i8** %4 to i8*
136   call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %5) #2
137   call void @llvm.va_start(i8* nonnull %5)
138   %6 = load i8*, i8** %4, align 8
139   %7 = call i64* @__local_stdio_printf_options() #2
140   %8 = load i64, i64* %7, align 8
141   %9 = or i64 %8, 2
142   %10 = call i32 @__stdio_common_vsprintf(i64 %9, i8* %0, i64 %1, i8* %2, i8* null, i8* %6) #2
143   %11 = icmp sgt i32 %10, -1
144   %12 = select i1 %11, i32 %10, i32 -1
145   call void @llvm.va_end(i8* nonnull %5)
146   call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %5) #2
147   ret i32 %12
150 attributes #6 = { "no-frame-pointer-elim"="true" }
152 ; CHECK-LABEL: vla
153 ; CHECK: str     x23, [sp, #-112]!
154 ; CHECK: stp     x21, x22, [sp, #16]
155 ; CHECK: stp     x19, x20, [sp, #32]
156 ; CHECK: stp     x29, x30, [sp, #48]
157 ; CHECK: add     x29, sp, #48
158 ; CHECK: add     x8, x29, #16
159 ; CHECK: stur    x8, [x29, #-40]
160 ; CHECK: mov     w8, w0
161 ; CHECK: add     x8, x8, #15
162 ; CHECK: lsr     x15, x8, #4
163 ; CHECK: mov     x19, x1
164 ; CHECK: mov     [[REG2:x[0-9]+]], sp
165 ; CHECK: stp     x2, x3, [x29, #16]
166 ; CHECK: stp     x4, x5, [x29, #32]
167 ; CHECK: stp     x6, x7, [x29, #48]
168 ; CHECK: bl      __chkstk
169 ; CHECK: mov     x8, sp
170 ; CHECK: sub     [[REG:x[0-9]+]], x8, x15, lsl #4
171 ; CHECK: mov     sp, [[REG]]
172 ; CHECK: ldur    [[REG3:x[0-9]+]], [x29, #-40]
173 ; CHECK: sxtw    [[REG4:x[0-9]+]], w0
174 ; CHECK: bl      __local_stdio_printf_options
175 ; CHECK: ldr     x8, [x0]
176 ; CHECK: mov     x1, [[REG]]
177 ; CHECK: mov     x2, [[REG4]]
178 ; CHECK: mov     x3, x19
179 ; CHECK: orr     x0, x8, #0x2
180 ; CHECK: mov     x4, xzr
181 ; CHECK: mov     x5, [[REG3]]
182 ; CHECK: bl      __stdio_common_vsprintf
183 ; CHECK: mov     sp, [[REG2]]
184 ; CHECK: sub     sp, x29, #48
185 ; CHECK: ldp     x29, x30, [sp, #48]
186 ; CHECK: ldp     x19, x20, [sp, #32]
187 ; CHECK: ldp     x21, x22, [sp, #16]
188 ; CHECK: ldr     x23, [sp], #112
189 ; CHECK: ret
190 define void @vla(i32, i8*, ...) local_unnamed_addr {
191   %3 = alloca i8*, align 8
192   %4 = bitcast i8** %3 to i8*
193   call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %4) #5
194   call void @llvm.va_start(i8* nonnull %4)
195   %5 = zext i32 %0 to i64
196   %6 = call i8* @llvm.stacksave()
197   %7 = alloca i8, i64 %5, align 1
198   %8 = load i8*, i8** %3, align 8
199   %9 = sext i32 %0 to i64
200   %10 = call i64* @__local_stdio_printf_options()
201   %11 = load i64, i64* %10, align 8
202   %12 = or i64 %11, 2
203   %13 = call i32 @__stdio_common_vsprintf(i64 %12, i8* nonnull %7, i64 %9, i8* %1, i8* null, i8* %8)
204   call void @llvm.va_end(i8* nonnull %4)
205   call void @llvm.stackrestore(i8* %6)
206   call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %4) #5
207   ret void
210 declare i8* @llvm.stacksave()
211 declare void @llvm.stackrestore(i8*)
213 ; CHECK-LABEL: snprintf
214 ; CHECK-DAG: sub     sp,  sp, #96
215 ; CHECK-DAG: str     x21, [sp, #16]
216 ; CHECK-DAG: stp     x19, x20, [sp, #24]
217 ; CHECK-DAG: str     x30, [sp, #40]
218 ; CHECK-DAG: add     x8, sp, #56
219 ; CHECK-DAG: mov     x19, x2
220 ; CHECK-DAG: mov     x20, x1
221 ; CHECK-DAG: mov     x21, x0
222 ; CHECK-DAG: stp     x3, x4, [sp, #56]
223 ; CHECK-DAG: stp     x5, x6, [sp, #72]
224 ; CHECK-DAG: str     x7, [sp, #88]
225 ; CHECK-DAG: str     x8, [sp, #8]
226 ; CHECK-DAG: bl      __local_stdio_printf_options
227 ; CHECK-DAG: ldr     x8, [x0]
228 ; CHECK-DAG: add     x5, sp, #56
229 ; CHECK-DAG: mov     x1, x21
230 ; CHECK-DAG: mov     x2, x20
231 ; CHECK-DAG: orr     x0, x8, #0x2
232 ; CHECK-DAG: mov     x3, x19
233 ; CHECK-DAG: mov     x4, xzr
234 ; CHECK-DAG: bl      __stdio_common_vsprintf
235 ; CHECK-DAG: ldr     x30, [sp, #40]
236 ; CHECK-DAG: ldp     x19, x20, [sp, #24]
237 ; CHECK-DAG: ldr     x21, [sp, #16]
238 ; CHECK-DAG: cmp     w0, #0
239 ; CHECK-DAG: csinv   w0, w0, wzr, ge
240 ; CHECK-DAG: add     sp, sp, #96
241 ; CHECK-DAG: ret
242 define i32 @snprintf(i8*, i64, i8*, ...) local_unnamed_addr #5 {
243   %4 = alloca i8*, align 8
244   %5 = bitcast i8** %4 to i8*
245   call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %5) #2
246   call void @llvm.va_start(i8* nonnull %5)
247   %6 = load i8*, i8** %4, align 8
248   %7 = call i64* @__local_stdio_printf_options() #2
249   %8 = load i64, i64* %7, align 8
250   %9 = or i64 %8, 2
251   %10 = call i32 @__stdio_common_vsprintf(i64 %9, i8* %0, i64 %1, i8* %2, i8* null, i8* %6) #2
252   %11 = icmp sgt i32 %10, -1
253   %12 = select i1 %11, i32 %10, i32 -1
254   call void @llvm.va_end(i8* nonnull %5)
255   call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %5) #2
256   ret i32 %12
259 ; CHECK-LABEL: fixed_params
260 ; CHECK: sub     sp,  sp, #32
261 ; CHECK-DAG: mov     w6,  w3
262 ; CHECK-DAG: mov     [[REG1:w[0-9]+]],  w2
263 ; CHECK: mov     w2, w1
264 ; CHECK: str     w4,  [sp]
265 ; CHECK: fmov    x1,  d0
266 ; CHECK: fmov    x3,  d1
267 ; CHECK: fmov    x5,  d2
268 ; CHECK: fmov    x7,  d3
269 ; CHECK: mov     w4,  [[REG1]]
270 ; CHECK: str     x30, [sp, #16]
271 ; CHECK: str     d4,  [sp, #8]
272 ; CHECK: bl      varargs
273 ; CHECK: ldr     x30, [sp, #16]
274 ; CHECK: add     sp,  sp, #32
275 ; CHECK: ret
276 define void @fixed_params(i32, double, i32, double, i32, double, i32, double, i32, double) nounwind {
277   tail call void (i32, ...) @varargs(i32 %0, double %1, i32 %2, double %3, i32 %4, double %5, i32 %6, double %7, i32 %8, double %9)
278   ret void
281 declare void @varargs(i32, ...) local_unnamed_addr