1 ; RUN: llc -mtriple=arm64ec-pc-windows-msvc < %s | FileCheck %s
3 declare void @no_op() nounwind;
4 ; CHECK-LABEL: .def $iexit_thunk$cdecl$v$v;
5 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$v$v
7 ; CHECK-NEXT: sub sp, sp, #48
8 ; CHECK-NEXT: .seh_stackalloc 48
9 ; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill
10 ; CHECK-NEXT: .seh_save_fplr 32
11 ; CHECK-NEXT: add x29, sp, #32
12 ; CHECK-NEXT: .seh_add_fp 32
13 ; CHECK-NEXT: .seh_endprologue
14 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
15 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
17 ; CHECK-NEXT: .seh_startepilogue
18 ; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload
19 ; CHECK-NEXT: .seh_save_fplr 32
20 ; CHECK-NEXT: add sp, sp, #48
21 ; CHECK-NEXT: .seh_stackalloc 48
22 ; CHECK-NEXT: .seh_endepilogue
24 ; CHECK-NEXT: .seh_endfunclet
25 ; CHECK-NEXT: .seh_endproc
26 ; CHECK-LABEL: .def "#no_op$exit_thunk";
27 ; CHECK: .section .wowthk$aa,"xr",discard,"#no_op$exit_thunk"
28 ; CHECK: .weak_anti_dep no_op
29 ; CHECK: .weak_anti_dep "#no_op"
31 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
32 ; CHECK-NEXT: .seh_save_reg_x x30, 16
33 ; CHECK-NEXT: .seh_endprologue
34 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
35 ; CHECK-NEXT: adrp x11, no_op
36 ; CHECK-NEXT: add x11, x11, :lo12:no_op
37 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
38 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$v$v)
39 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$v$v)
41 ; CHECK-NEXT: .seh_startepilogue
42 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
43 ; CHECK-NEXT: .seh_save_reg_x x30, 16
44 ; CHECK-NEXT: .seh_endepilogue
46 ; CHECK-NEXT: .seh_endfunclet
47 ; CHECK-NEXT: .seh_endproc
49 declare i64 @simple_integers(i8, i16, i32, i64) nounwind;
50 ; CHECK-LABEL: .def $iexit_thunk$cdecl$i8$i8i8i8i8;
51 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$i8$i8i8i8i8
53 ; CHECK-NEXT: sub sp, sp, #48
54 ; CHECK-NEXT: .seh_stackalloc 48
55 ; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill
56 ; CHECK-NEXT: .seh_save_fplr 32
57 ; CHECK-NEXT: add x29, sp, #32
58 ; CHECK-NEXT: .seh_add_fp 32
59 ; CHECK-NEXT: .seh_endprologue
60 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
61 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
63 ; CHECK-NEXT: mov x0, x8
64 ; CHECK-NEXT: .seh_startepilogue
65 ; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload
66 ; CHECK-NEXT: .seh_save_fplr 32
67 ; CHECK-NEXT: add sp, sp, #48
68 ; CHECK-NEXT: .seh_stackalloc 48
69 ; CHECK-NEXT: .seh_endepilogue
71 ; CHECK-NEXT: .seh_endfunclet
72 ; CHECK-NEXT: .seh_endproc
73 ; CHECK-LABEL: .def "#simple_integers$exit_thunk";
74 ; CHECK: .section .wowthk$aa,"xr",discard,"#simple_integers$exit_thunk"
75 ; CHECK: .weak_anti_dep simple_integers
76 ; CHECK: .weak_anti_dep "#simple_integers"
78 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
79 ; CHECK-NEXT: .seh_save_reg_x x30, 16
80 ; CHECK-NEXT: .seh_endprologue
81 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
82 ; CHECK-NEXT: adrp x11, simple_integers
83 ; CHECK-NEXT: add x11, x11, :lo12:simple_integers
84 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
85 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$i8$i8i8i8i8)
86 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$i8$i8i8i8i8)
88 ; CHECK-NEXT: .seh_startepilogue
89 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
90 ; CHECK-NEXT: .seh_save_reg_x x30, 16
91 ; CHECK-NEXT: .seh_endepilogue
93 ; CHECK-NEXT: .seh_endfunclet
94 ; CHECK-NEXT: .seh_endproc
96 ; NOTE: Only float and double are supported.
97 declare double @simple_floats(float, double) nounwind;
98 ; CHECK-LABEL: .def $iexit_thunk$cdecl$d$fd;
99 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$d$fd
101 ; CHECK-NEXT: sub sp, sp, #48
102 ; CHECK-NEXT: .seh_stackalloc 48
103 ; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill
104 ; CHECK-NEXT: .seh_save_fplr 32
105 ; CHECK-NEXT: add x29, sp, #32
106 ; CHECK-NEXT: .seh_add_fp 32
107 ; CHECK-NEXT: .seh_endprologue
108 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
109 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
110 ; CHECK-NEXT: blr x16
111 ; CHECK-NEXT: .seh_startepilogue
112 ; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload
113 ; CHECK-NEXT: .seh_save_fplr 32
114 ; CHECK-NEXT: add sp, sp, #48
115 ; CHECK-NEXT: .seh_stackalloc 48
116 ; CHECK-NEXT: .seh_endepilogue
118 ; CHECK-NEXT: .seh_endfunclet
119 ; CHECK-NEXT: .seh_endproc
120 ; CHECK-LABEL: .def "#simple_floats$exit_thunk";
121 ; CHECK: .section .wowthk$aa,"xr",discard,"#simple_floats$exit_thunk"
122 ; CHECK: .weak_anti_dep simple_floats
123 ; CHECK: .weak_anti_dep "#simple_floats"
125 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
126 ; CHECK-NEXT: .seh_save_reg_x x30, 16
127 ; CHECK-NEXT: .seh_endprologue
128 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
129 ; CHECK-NEXT: adrp x11, simple_floats
130 ; CHECK-NEXT: add x11, x11, :lo12:simple_floats
131 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
132 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$d$fd)
133 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$d$fd)
135 ; CHECK-NEXT: .seh_startepilogue
136 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
137 ; CHECK-NEXT: .seh_save_reg_x x30, 16
138 ; CHECK-NEXT: .seh_endepilogue
140 ; CHECK-NEXT: .seh_endfunclet
141 ; CHECK-NEXT: .seh_endproc
143 declare void @has_varargs(...) nounwind;
144 ; CHECK-LABEL: .def $iexit_thunk$cdecl$v$varargs;
145 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$v$varargs
147 ; CHECK-NEXT: sub sp, sp, #64
148 ; CHECK-NEXT: .seh_stackalloc 64
149 ; CHECK-NEXT: stp x29, x30, [sp, #48] // 16-byte Folded Spill
150 ; CHECK-NEXT: .seh_save_fplr 48
151 ; CHECK-NEXT: add x29, sp, #48
152 ; CHECK-NEXT: .seh_add_fp 48
153 ; CHECK-NEXT: .seh_endprologue
154 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
155 ; CHECK-NEXT: stp x4, x5, [sp, #32]
156 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
157 ; CHECK-NEXT: blr x16
158 ; CHECK-NEXT: .seh_startepilogue
159 ; CHECK-NEXT: ldp x29, x30, [sp, #48] // 16-byte Folded Reload
160 ; CHECK-NEXT: .seh_save_fplr 48
161 ; CHECK-NEXT: add sp, sp, #64
162 ; CHECK-NEXT: .seh_stackalloc 64
163 ; CHECK-NEXT: .seh_endepilogue
165 ; CHECK-NEXT: .seh_endfunclet
166 ; CHECK-NEXT: .seh_endproc
167 ; CHECK-LABEL: .def "#has_varargs$exit_thunk";
168 ; CHECK: .section .wowthk$aa,"xr",discard,"#has_varargs$exit_thunk"
169 ; CHECK: .weak_anti_dep has_varargs
170 ; CHECK: .weak_anti_dep "#has_varargs"
172 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
173 ; CHECK-NEXT: .seh_save_reg_x x30, 16
174 ; CHECK-NEXT: .seh_endprologue
175 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
176 ; CHECK-NEXT: adrp x11, has_varargs
177 ; CHECK-NEXT: add x11, x11, :lo12:has_varargs
178 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
179 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$v$varargs)
180 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$v$varargs)
182 ; CHECK-NEXT: .seh_startepilogue
183 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
184 ; CHECK-NEXT: .seh_save_reg_x x30, 16
185 ; CHECK-NEXT: .seh_endepilogue
187 ; CHECK-NEXT: .seh_endfunclet
188 ; CHECK-NEXT: .seh_endproc
190 declare void @has_sret(ptr sret([100 x i8])) nounwind;
191 ; CHECK-LABEL: .def $iexit_thunk$cdecl$m100$v;
192 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m100$v
194 ; CHECK-NEXT: sub sp, sp, #48
195 ; CHECK-NEXT: .seh_stackalloc 48
196 ; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill
197 ; CHECK-NEXT: .seh_save_fplr 32
198 ; CHECK-NEXT: add x29, sp, #32
199 ; CHECK-NEXT: .seh_add_fp 32
200 ; CHECK-NEXT: .seh_endprologue
201 ; CHECK-NEXT: mov x0, x8
202 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
203 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
204 ; CHECK-NEXT: blr x16
205 ; CHECK-NEXT: .seh_startepilogue
206 ; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload
207 ; CHECK-NEXT: .seh_save_fplr 32
208 ; CHECK-NEXT: add sp, sp, #48
209 ; CHECK-NEXT: .seh_stackalloc 48
210 ; CHECK-NEXT: .seh_endepilogue
212 ; CHECK-NEXT: .seh_endfunclet
213 ; CHECK-NEXT: .seh_endproc
214 ; CHECK-LABEL: .def "#has_sret$exit_thunk";
215 ; CHECK: .section .wowthk$aa,"xr",discard,"#has_sret$exit_thunk"
216 ; CHECK: .weak_anti_dep has_sret
217 ; CHECK: .weak_anti_dep "#has_sret"
219 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
220 ; CHECK-NEXT: .seh_save_reg_x x30, 16
221 ; CHECK-NEXT: .seh_endprologue
222 ; CHECK-NEXT: adrp x9, __os_arm64x_check_icall
223 ; CHECK-NEXT: adrp x11, has_sret
224 ; CHECK-NEXT: add x11, x11, :lo12:has_sret
225 ; CHECK-NEXT: ldr x9, [x9, :lo12:__os_arm64x_check_icall]
226 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$m100$v)
227 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$m100$v)
229 ; CHECK-NEXT: .seh_startepilogue
230 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
231 ; CHECK-NEXT: .seh_save_reg_x x30, 16
232 ; CHECK-NEXT: .seh_endepilogue
234 ; CHECK-NEXT: .seh_endfunclet
235 ; CHECK-NEXT: .seh_endproc
237 %TSRet = type { i64, i64 }
238 declare void @has_aligned_sret(ptr align 32 sret(%TSRet)) nounwind;
239 ; CHECK-LABEL: .def $iexit_thunk$cdecl$m16$v;
240 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m16$v
242 ; CHECK-NEXT: sub sp, sp, #48
243 ; CHECK-NEXT: .seh_stackalloc 48
244 ; CHECK-NEXT: stp x29, x30, [sp, #32] // 16-byte Folded Spill
245 ; CHECK-NEXT: .seh_save_fplr 32
246 ; CHECK-NEXT: add x29, sp, #32
247 ; CHECK-NEXT: .seh_add_fp 32
248 ; CHECK-NEXT: .seh_endprologue
249 ; CHECK-NEXT: mov x0, x8
250 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
251 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
252 ; CHECK-NEXT: blr x16
253 ; CHECK-NEXT: .seh_startepilogue
254 ; CHECK-NEXT: ldp x29, x30, [sp, #32] // 16-byte Folded Reload
255 ; CHECK-NEXT: .seh_save_fplr 32
256 ; CHECK-NEXT: add sp, sp, #48
257 ; CHECK-NEXT: .seh_stackalloc 48
258 ; CHECK-NEXT: .seh_endepilogue
260 ; CHECK-NEXT: .seh_endfunclet
261 ; CHECK-NEXT: .seh_endproc
262 ; CHECK-LABEL: .def "#has_aligned_sret$exit_thunk";
263 ; CHECK: .section .wowthk$aa,"xr",discard,"#has_aligned_sret$exit_thunk"
264 ; CHECK: .weak_anti_dep has_aligned_sret
265 ; CHECK: .weak_anti_dep "#has_aligned_sret"
267 ; CHECK: str x30, [sp, #-16]! // 8-byte Folded Spill
268 ; CHECK: .seh_save_reg_x x30, 16
269 ; CHECK: .seh_endprologue
270 ; CHECK: adrp x9, __os_arm64x_check_icall
271 ; CHECK: adrp x11, has_aligned_sret
272 ; CHECK: add x11, x11, :lo12:has_aligned_sret
273 ; CHECK: ldr x9, [x9, :lo12:__os_arm64x_check_icall]
274 ; CHECK: adrp x10, ($iexit_thunk$cdecl$m16$v)
275 ; CHECK: add x10, x10, :lo12:($iexit_thunk$cdecl$m16$v)
277 ; CHECK: .seh_startepilogue
278 ; CHECK: ldr x30, [sp], #16 // 8-byte Folded Reload
279 ; CHECK: .seh_save_reg_x x30, 16
280 ; CHECK: .seh_endepilogue
282 ; CHECK: .seh_endfunclet
283 ; CHECK: .seh_endproc
285 declare [2 x i8] @small_array([2 x i8], [2 x float]) nounwind;
286 ; CHECK-LABEL: .def $iexit_thunk$cdecl$m2$m2F8;
287 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m2$m2F8
289 ; CHECK-NEXT: sub sp, sp, #64
290 ; CHECK-NEXT: .seh_stackalloc 64
291 ; CHECK-NEXT: stp x29, x30, [sp, #48] // 16-byte Folded Spill
292 ; CHECK-NEXT: .seh_save_fplr 48
293 ; CHECK-NEXT: add x29, sp, #48
294 ; CHECK-NEXT: .seh_add_fp 48
295 ; CHECK-NEXT: .seh_endprologue
296 ; CHECK-NEXT: sturb w1, [x29, #-1]
297 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
298 ; CHECK-NEXT: sturb w0, [x29, #-2]
299 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
300 ; CHECK-NEXT: stp s0, s1, [x29, #-12]
301 ; CHECK-NEXT: ldurh w0, [x29, #-2]
302 ; CHECK-NEXT: ldur x1, [x29, #-12]
303 ; CHECK-NEXT: blr x16
304 ; CHECK-NEXT: mov w0, w8
305 ; CHECK-NEXT: sturh w8, [x29, #-14]
306 ; CHECK-NEXT: ubfx w1, w8, #8, #8
307 ; CHECK-NEXT: .seh_startepilogue
308 ; CHECK-NEXT: ldp x29, x30, [sp, #48] // 16-byte Folded Reload
309 ; CHECK-NEXT: .seh_save_fplr 48
310 ; CHECK-NEXT: add sp, sp, #64
311 ; CHECK-NEXT: .seh_stackalloc 64
312 ; CHECK-NEXT: .seh_endepilogue
314 ; CHECK-NEXT: .seh_endfunclet
315 ; CHECK-NEXT: .seh_endproc
316 ; CHECK-LABEL: .def "#small_array$exit_thunk";
317 ; CHECK: .section .wowthk$aa,"xr",discard,"#small_array$exit_thunk"
318 ; CHECK: .weak_anti_dep small_array
319 ; CHECK: .weak_anti_dep "#small_array"
321 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
322 ; CHECK-NEXT: .seh_save_reg_x x30, 16
323 ; CHECK-NEXT: .seh_endprologue
324 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
325 ; CHECK-NEXT: adrp x11, small_array
326 ; CHECK-NEXT: add x11, x11, :lo12:small_array
327 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
328 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$m2$m2F8)
329 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$m2$m2F8)
331 ; CHECK-NEXT: .seh_startepilogue
332 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
333 ; CHECK-NEXT: .seh_save_reg_x x30, 16
334 ; CHECK-NEXT: .seh_endepilogue
336 ; CHECK-NEXT: .seh_endfunclet
337 ; CHECK-NEXT: .seh_endproc
339 declare [3 x i64] @large_array([3 x i64], [2 x double], [2 x [2 x i64]]) nounwind;
340 ; CHECK-LABEL: .def $iexit_thunk$cdecl$m24$m24D16m32;
341 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m24$m24D16m32
343 ; CHECK-NEXT: sub sp, sp, #144
344 ; CHECK-NEXT: .seh_stackalloc 144
345 ; CHECK-NEXT: stp x29, x30, [sp, #128] // 16-byte Folded Spill
346 ; CHECK-NEXT: .seh_save_fplr 128
347 ; CHECK-NEXT: add x29, sp, #128
348 ; CHECK-NEXT: .seh_add_fp 128
349 ; CHECK-NEXT: .seh_endprologue
350 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
351 ; CHECK-NEXT: stp x0, x1, [x29, #-48]
352 ; CHECK-NEXT: sub x0, x29, #24
353 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
354 ; CHECK-NEXT: stur x2, [x29, #-32]
355 ; CHECK-NEXT: sub x1, x29, #48
356 ; CHECK-NEXT: stp x3, x4, [sp, #32]
357 ; CHECK-NEXT: add x2, sp, #64
358 ; CHECK-NEXT: add x3, sp, #32
359 ; CHECK-NEXT: stp d0, d1, [sp, #64]
360 ; CHECK-NEXT: stp x5, x6, [sp, #48]
361 ; CHECK-NEXT: blr x16
362 ; CHECK-NEXT: ldp x0, x1, [x29, #-24]
363 ; CHECK-NEXT: ldur x2, [x29, #-8]
364 ; CHECK-NEXT: .seh_startepilogue
365 ; CHECK-NEXT: ldp x29, x30, [sp, #128] // 16-byte Folded Reload
366 ; CHECK-NEXT: .seh_save_fplr 128
367 ; CHECK-NEXT: add sp, sp, #144
368 ; CHECK-NEXT: .seh_stackalloc 144
369 ; CHECK-NEXT: .seh_endepilogue
371 ; CHECK-NEXT: .seh_endfunclet
372 ; CHECK-NEXT: .seh_endproc
373 ; CHECK-LABEL: .def "#large_array$exit_thunk";
374 ; CHECK: .section .wowthk$aa,"xr",discard,"#large_array$exit_thunk"
375 ; CHECK: .weak_anti_dep large_array
376 ; CHECK: .weak_anti_dep "#large_array"
378 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
379 ; CHECK-NEXT: .seh_save_reg_x x30, 16
380 ; CHECK-NEXT: .seh_endprologue
381 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
382 ; CHECK-NEXT: adrp x11, large_array
383 ; CHECK-NEXT: add x11, x11, :lo12:large_array
384 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
385 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$m24$m24D16m32)
386 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$m24$m24D16m32)
388 ; CHECK-NEXT: .seh_startepilogue
389 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
390 ; CHECK-NEXT: .seh_save_reg_x x30, 16
391 ; CHECK-NEXT: .seh_endepilogue
393 ; CHECK-NEXT: .seh_endfunclet
394 ; CHECK-NEXT: .seh_endproc
397 %T2 = type { i32, float }
398 %T3 = type { i64, double }
399 %T4 = type { i64, double, i8 }
400 declare %T2 @simple_struct(%T1, %T2, %T3, %T4) nounwind;
401 ; CHECK-LABEL: .def $iexit_thunk$cdecl$m8$i8m8m16m24;
402 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m8$i8m8m16m24
404 ; CHECK-NEXT: sub sp, sp, #112
405 ; CHECK-NEXT: .seh_stackalloc 112
406 ; CHECK-NEXT: stp x29, x30, [sp, #96] // 16-byte Folded Spill
407 ; CHECK-NEXT: .seh_save_fplr 96
408 ; CHECK-NEXT: add x29, sp, #96
409 ; CHECK-NEXT: .seh_add_fp 96
410 ; CHECK-NEXT: .seh_endprologue
411 ; CHECK-NEXT: stur w1, [x29, #-8]
412 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
413 ; CHECK-NEXT: stur s0, [x29, #-4]
414 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
415 ; CHECK-NEXT: ldur x1, [x29, #-8]
416 ; CHECK-NEXT: stur x2, [x29, #-24]
417 ; CHECK-NEXT: sub x2, x29, #24
418 ; CHECK-NEXT: str x3, [sp, #48]
419 ; CHECK-NEXT: add x3, sp, #48
420 ; CHECK-NEXT: stur d1, [x29, #-16]
421 ; CHECK-NEXT: str d2, [sp, #56]
422 ; CHECK-NEXT: strb w4, [sp, #64]
423 ; CHECK-NEXT: blr x16
424 ; CHECK-NEXT: str x8, [sp, #40]
425 ; CHECK-NEXT: mov x0, x8
426 ; CHECK-NEXT: ldr s0, [sp, #44]
427 ; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
428 ; CHECK-NEXT: .seh_startepilogue
429 ; CHECK-NEXT: ldp x29, x30, [sp, #96] // 16-byte Folded Reload
430 ; CHECK-NEXT: .seh_save_fplr 96
431 ; CHECK-NEXT: add sp, sp, #112
432 ; CHECK-NEXT: .seh_stackalloc 112
433 ; CHECK-NEXT: .seh_endepilogue
435 ; CHECK-NEXT: .seh_endfunclet
436 ; CHECK-NEXT: .seh_endproc
437 ; CHECK-LABEL: .def "#simple_struct$exit_thunk";
438 ; CHECK: .section .wowthk$aa,"xr",discard,"#simple_struct$exit_thunk"
439 ; CHECK: .weak_anti_dep simple_struct
440 ; CHECK: .weak_anti_dep "#simple_struct"
442 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
443 ; CHECK-NEXT: .seh_save_reg_x x30, 16
444 ; CHECK-NEXT: .seh_endprologue
445 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
446 ; CHECK-NEXT: adrp x11, simple_struct
447 ; CHECK-NEXT: add x11, x11, :lo12:simple_struct
448 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
449 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$m8$i8m8m16m24)
450 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$m8$i8m8m16m24)
452 ; CHECK-NEXT: .seh_startepilogue
453 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
454 ; CHECK-NEXT: .seh_save_reg_x x30, 16
455 ; CHECK-NEXT: .seh_endepilogue
457 ; CHECK-NEXT: .seh_endfunclet
458 ; CHECK-NEXT: .seh_endproc
460 declare <4 x i8> @small_vector(<4 x i8> %0) nounwind;
461 ; CHECK-LABEL: .def $iexit_thunk$cdecl$m$m;
462 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m$m
464 ; CHECK-NEXT: sub sp, sp, #64
465 ; CHECK-NEXT: .seh_stackalloc 64
466 ; CHECK-NEXT: stp x29, x30, [sp, #48] // 16-byte Folded Spill
467 ; CHECK-NEXT: .seh_save_fplr 48
468 ; CHECK-NEXT: add x29, sp, #48
469 ; CHECK-NEXT: .seh_add_fp 48
470 ; CHECK-NEXT: .seh_endprologue
471 ; CHECK-NEXT: uzp1 v0.8b, v0.8b, v0.8b
472 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
473 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
474 ; CHECK-NEXT: fmov w0, s0
475 ; CHECK-NEXT: stur s0, [x29, #-4]
476 ; CHECK-NEXT: blr x16
477 ; CHECK-NEXT: stur w8, [x29, #-8]
478 ; CHECK-NEXT: ldur s0, [x29, #-8]
479 ; CHECK-NEXT: ushll v0.8h, v0.8b, #0
480 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
481 ; CHECK-NEXT: .seh_startepilogue
482 ; CHECK-NEXT: ldp x29, x30, [sp, #48] // 16-byte Folded Reload
483 ; CHECK-NEXT: .seh_save_fplr 48
484 ; CHECK-NEXT: add sp, sp, #64
485 ; CHECK-NEXT: .seh_stackalloc 64
486 ; CHECK-NEXT: .seh_endepilogue
488 ; CHECK-NEXT: .seh_endfunclet
489 ; CHECK-NEXT: .seh_endproc
490 ; CHECK-LABEL: .def "#small_vector$exit_thunk";
491 ; CHECK: .section .wowthk$aa,"xr",discard,"#small_vector$exit_thunk"
492 ; CHECK: .weak_anti_dep small_vector
493 ; CHECK: .weak_anti_dep "#small_vector"
495 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
496 ; CHECK-NEXT: .seh_save_reg_x x30, 16
497 ; CHECK-NEXT: .seh_endprologue
498 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
499 ; CHECK-NEXT: adrp x11, small_vector
500 ; CHECK-NEXT: add x11, x11, :lo12:small_vector
501 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
502 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$m$m)
503 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$m$m)
505 ; CHECK-NEXT: .seh_startepilogue
506 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
507 ; CHECK-NEXT: .seh_save_reg_x x30, 16
508 ; CHECK-NEXT: .seh_endepilogue
510 ; CHECK-NEXT: .seh_endfunclet
511 ; CHECK-NEXT: .seh_endproc
513 declare <8 x i16> @large_vector(<8 x i16> %0) nounwind;
514 ; CHECK-LABEL: .def $iexit_thunk$cdecl$m16$m16;
515 ; CHECK: .section .wowthk$aa,"xr",discard,$iexit_thunk$cdecl$m16$m16
517 ; CHECK-NEXT: sub sp, sp, #80
518 ; CHECK-NEXT: .seh_stackalloc 80
519 ; CHECK-NEXT: stp x29, x30, [sp, #64] // 16-byte Folded Spill
520 ; CHECK-NEXT: .seh_save_fplr 64
521 ; CHECK-NEXT: add x29, sp, #64
522 ; CHECK-NEXT: .seh_add_fp 64
523 ; CHECK-NEXT: .seh_endprologue
524 ; CHECK-NEXT: adrp x8, __os_arm64x_dispatch_call_no_redirect
525 ; CHECK-NEXT: sub x0, x29, #16
526 ; CHECK-NEXT: add x1, sp, #32
527 ; CHECK-NEXT: ldr x16, [x8, :lo12:__os_arm64x_dispatch_call_no_redirect]
528 ; CHECK-NEXT: str q0, [sp, #32]
529 ; CHECK-NEXT: blr x16
530 ; CHECK-NEXT: ldur q0, [x29, #-16]
531 ; CHECK-NEXT: .seh_startepilogue
532 ; CHECK-NEXT: ldp x29, x30, [sp, #64] // 16-byte Folded Reload
533 ; CHECK-NEXT: .seh_save_fplr 64
534 ; CHECK-NEXT: add sp, sp, #80
535 ; CHECK-NEXT: .seh_stackalloc 80
536 ; CHECK-NEXT: .seh_endepilogue
538 ; CHECK-NEXT: .seh_endfunclet
539 ; CHECK-NEXT: .seh_endproc
540 ; CHECK-LABEL: .def "#large_vector$exit_thunk";
541 ; CHECK: .section .wowthk$aa,"xr",discard,"#large_vector$exit_thunk"
542 ; CHECK: .weak_anti_dep large_vector
543 ; CHECK: .weak_anti_dep "#large_vector"
545 ; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
546 ; CHECK-NEXT: .seh_save_reg_x x30, 16
547 ; CHECK-NEXT: .seh_endprologue
548 ; CHECK-NEXT: adrp x8, __os_arm64x_check_icall
549 ; CHECK-NEXT: adrp x11, large_vector
550 ; CHECK-NEXT: add x11, x11, :lo12:large_vector
551 ; CHECK-NEXT: ldr x8, [x8, :lo12:__os_arm64x_check_icall]
552 ; CHECK-NEXT: adrp x10, ($iexit_thunk$cdecl$m16$m16)
553 ; CHECK-NEXT: add x10, x10, :lo12:($iexit_thunk$cdecl$m16$m16)
555 ; CHECK-NEXT: .seh_startepilogue
556 ; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
557 ; CHECK-NEXT: .seh_save_reg_x x30, 16
558 ; CHECK-NEXT: .seh_endepilogue
560 ; CHECK-NEXT: .seh_endfunclet
561 ; CHECK-NEXT: .seh_endproc
563 ; CHECK-LABEL: .section .hybmp$x,"yi"
564 ; CHECK-NEXT: .symidx "#func_caller"
565 ; CHECK-NEXT: .symidx $ientry_thunk$cdecl$v$v
566 ; CHECK-NEXT: .word 1
567 ; CHECK-NEXT: .symidx no_op
568 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$v$v
569 ; CHECK-NEXT: .word 4
570 ; CHECK-NEXT: .symidx "#no_op$exit_thunk"
571 ; CHECK-NEXT: .symidx no_op
572 ; CHECK-NEXT: .word 0
573 ; CHECK-NEXT: .symidx simple_integers
574 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$i8$i8i8i8i8
575 ; CHECK-NEXT: .word 4
576 ; CHECK-NEXT: .symidx "#simple_integers$exit_thunk"
577 ; CHECK-NEXT: .symidx simple_integers
578 ; CHECK-NEXT: .word 0
579 ; CHECK-NEXT: .symidx simple_floats
580 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$d$fd
581 ; CHECK-NEXT: .word 4
582 ; CHECK-NEXT: .symidx "#simple_floats$exit_thunk"
583 ; CHECK-NEXT: .symidx simple_floats
584 ; CHECK-NEXT: .word 0
585 ; CHECK-NEXT: .symidx has_varargs
586 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$v$varargs
587 ; CHECK-NEXT: .word 4
588 ; CHECK-NEXT: .symidx "#has_varargs$exit_thunk"
589 ; CHECK-NEXT: .symidx has_varargs
590 ; CHECK-NEXT: .word 0
591 ; CHECK-NEXT: .symidx has_sret
592 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m100$v
593 ; CHECK-NEXT: .word 4
594 ; CHECK-NEXT: .symidx "#has_sret$exit_thunk"
595 ; CHECK-NEXT: .symidx has_sret
596 ; CHECK-NEXT: .word 0
597 ; CHECK-NEXT: .symidx has_aligned_sret
598 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m16$v
599 ; CHECK-NEXT: .word 4
600 ; CHECK-NEXT: .symidx "#has_aligned_sret$exit_thunk"
601 ; CHECK-NEXT: .symidx has_aligned_sret
602 ; CHECK-NEXT: .word 0
603 ; CHECK-NEXT: .symidx small_array
604 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m2$m2F8
605 ; CHECK-NEXT: .word 4
606 ; CHECK-NEXT: .symidx "#small_array$exit_thunk"
607 ; CHECK-NEXT: .symidx small_array
608 ; CHECK-NEXT: .word 0
609 ; CHECK-NEXT: .symidx large_array
610 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m24$m24D16m32
611 ; CHECK-NEXT: .word 4
612 ; CHECK-NEXT: .symidx "#large_array$exit_thunk"
613 ; CHECK-NEXT: .symidx large_array
614 ; CHECK-NEXT: .word 0
615 ; CHECK-NEXT: .symidx simple_struct
616 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m8$i8m8m16m24
617 ; CHECK-NEXT: .word 4
618 ; CHECK-NEXT: .symidx "#simple_struct$exit_thunk"
619 ; CHECK-NEXT: .symidx simple_struct
620 ; CHECK-NEXT: .word 0
621 ; CHECK-NEXT: .symidx small_vector
622 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m$m
623 ; CHECK-NEXT: .word 4
624 ; CHECK-NEXT: .symidx "#small_vector$exit_thunk"
625 ; CHECK-NEXT: .symidx small_vector
626 ; CHECK-NEXT: .word 0
627 ; CHECK-NEXT: .symidx large_vector
628 ; CHECK-NEXT: .symidx $iexit_thunk$cdecl$m16$m16
629 ; CHECK-NEXT: .word 4
630 ; CHECK-NEXT: .symidx "#large_vector$exit_thunk"
631 ; CHECK-NEXT: .symidx large_vector
632 ; CHECK-NEXT: .word 0
634 define void @func_caller() nounwind {
636 call i64 @simple_integers(i8 0, i16 0, i32 0, i64 0)
637 call double @simple_floats(float 0.0, double 0.0)
638 call void (...) @has_varargs()
640 call void @has_sret(ptr sret([100 x i8]) %c)
641 %aligned = alloca %TSRet, align 32
642 store %TSRet { i64 0, i64 0 }, ptr %aligned, align 32
643 call void @has_aligned_sret(ptr align 32 sret(%TSRet) %aligned)
644 call [2 x i8] @small_array([2 x i8] [i8 0, i8 0], [2 x float] [float 0.0, float 0.0])
645 call [3 x i64] @large_array([3 x i64] [i64 0, i64 0, i64 0], [2 x double] [double 0.0, double 0.0], [2 x [2 x i64]] [[2 x i64] [i64 0, i64 0], [2 x i64] [i64 0, i64 0]])
646 call %T2 @simple_struct(%T1 { i16 0 }, %T2 { i32 0, float 0.0 }, %T3 { i64 0, double 0.0 }, %T4 { i64 0, double 0.0, i8 0 })
647 call <4 x i8> @small_vector(<4 x i8> <i8 0, i8 0, i8 0, i8 0>)
648 call <8 x i16> @large_vector(<8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0>)