xref: /llvm-project/llvm/test/CodeGen/AArch64/preserve_nonecc_call.ll (revision f05fa6e0cfdc61f29bac94b157a56e048d10efd1)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck --check-prefixes=CHECK %s
3; RUN: llc -mtriple=aarch64-apple-darwin < %s | FileCheck --check-prefixes=DARWIN %s
4; RUN: llc -mtriple=aarch64-pc-windows < %s | FileCheck --check-prefixes=WIN %s
5
6; This test checks various function call behaviors between preserve_none and
7; normal calling conventions.
8
9declare preserve_nonecc void @callee(ptr)
10
11; Normal caller calls preserve_none callee. Will not generated tail call because
12; of incompatible calling convention. Callee saved registers are saved/restored
13; around the call.
14define void @caller1(ptr %a) {
15; CHECK-LABEL: caller1:
16; CHECK:       // %bb.0:
17; CHECK-NEXT:    stp d15, d14, [sp, #-160]! // 16-byte Folded Spill
18; CHECK-NEXT:    stp d13, d12, [sp, #16] // 16-byte Folded Spill
19; CHECK-NEXT:    stp d11, d10, [sp, #32] // 16-byte Folded Spill
20; CHECK-NEXT:    stp d9, d8, [sp, #48] // 16-byte Folded Spill
21; CHECK-NEXT:    str x30, [sp, #64] // 8-byte Folded Spill
22; CHECK-NEXT:    stp x28, x27, [sp, #80] // 16-byte Folded Spill
23; CHECK-NEXT:    stp x26, x25, [sp, #96] // 16-byte Folded Spill
24; CHECK-NEXT:    stp x24, x23, [sp, #112] // 16-byte Folded Spill
25; CHECK-NEXT:    stp x22, x21, [sp, #128] // 16-byte Folded Spill
26; CHECK-NEXT:    stp x20, x19, [sp, #144] // 16-byte Folded Spill
27; CHECK-NEXT:    .cfi_def_cfa_offset 160
28; CHECK-NEXT:    .cfi_offset w19, -8
29; CHECK-NEXT:    .cfi_offset w20, -16
30; CHECK-NEXT:    .cfi_offset w21, -24
31; CHECK-NEXT:    .cfi_offset w22, -32
32; CHECK-NEXT:    .cfi_offset w23, -40
33; CHECK-NEXT:    .cfi_offset w24, -48
34; CHECK-NEXT:    .cfi_offset w25, -56
35; CHECK-NEXT:    .cfi_offset w26, -64
36; CHECK-NEXT:    .cfi_offset w27, -72
37; CHECK-NEXT:    .cfi_offset w28, -80
38; CHECK-NEXT:    .cfi_offset w30, -96
39; CHECK-NEXT:    .cfi_offset b8, -104
40; CHECK-NEXT:    .cfi_offset b9, -112
41; CHECK-NEXT:    .cfi_offset b10, -120
42; CHECK-NEXT:    .cfi_offset b11, -128
43; CHECK-NEXT:    .cfi_offset b12, -136
44; CHECK-NEXT:    .cfi_offset b13, -144
45; CHECK-NEXT:    .cfi_offset b14, -152
46; CHECK-NEXT:    .cfi_offset b15, -160
47; CHECK-NEXT:    mov x20, x0
48; CHECK-NEXT:    bl callee
49; CHECK-NEXT:    ldp x20, x19, [sp, #144] // 16-byte Folded Reload
50; CHECK-NEXT:    ldr x30, [sp, #64] // 8-byte Folded Reload
51; CHECK-NEXT:    ldp x22, x21, [sp, #128] // 16-byte Folded Reload
52; CHECK-NEXT:    ldp x24, x23, [sp, #112] // 16-byte Folded Reload
53; CHECK-NEXT:    ldp x26, x25, [sp, #96] // 16-byte Folded Reload
54; CHECK-NEXT:    ldp x28, x27, [sp, #80] // 16-byte Folded Reload
55; CHECK-NEXT:    ldp d9, d8, [sp, #48] // 16-byte Folded Reload
56; CHECK-NEXT:    ldp d11, d10, [sp, #32] // 16-byte Folded Reload
57; CHECK-NEXT:    ldp d13, d12, [sp, #16] // 16-byte Folded Reload
58; CHECK-NEXT:    ldp d15, d14, [sp], #160 // 16-byte Folded Reload
59; CHECK-NEXT:    ret
60;
61; DARWIN-LABEL: caller1:
62; DARWIN:       ; %bb.0:
63; DARWIN-NEXT:    stp d15, d14, [sp, #-160]! ; 16-byte Folded Spill
64; DARWIN-NEXT:    stp d13, d12, [sp, #16] ; 16-byte Folded Spill
65; DARWIN-NEXT:    stp d11, d10, [sp, #32] ; 16-byte Folded Spill
66; DARWIN-NEXT:    stp d9, d8, [sp, #48] ; 16-byte Folded Spill
67; DARWIN-NEXT:    stp x28, x27, [sp, #64] ; 16-byte Folded Spill
68; DARWIN-NEXT:    stp x26, x25, [sp, #80] ; 16-byte Folded Spill
69; DARWIN-NEXT:    stp x24, x23, [sp, #96] ; 16-byte Folded Spill
70; DARWIN-NEXT:    stp x22, x21, [sp, #112] ; 16-byte Folded Spill
71; DARWIN-NEXT:    stp x20, x19, [sp, #128] ; 16-byte Folded Spill
72; DARWIN-NEXT:    stp x29, x30, [sp, #144] ; 16-byte Folded Spill
73; DARWIN-NEXT:    .cfi_def_cfa_offset 160
74; DARWIN-NEXT:    .cfi_offset w30, -8
75; DARWIN-NEXT:    .cfi_offset w29, -16
76; DARWIN-NEXT:    .cfi_offset w19, -24
77; DARWIN-NEXT:    .cfi_offset w20, -32
78; DARWIN-NEXT:    .cfi_offset w21, -40
79; DARWIN-NEXT:    .cfi_offset w22, -48
80; DARWIN-NEXT:    .cfi_offset w23, -56
81; DARWIN-NEXT:    .cfi_offset w24, -64
82; DARWIN-NEXT:    .cfi_offset w25, -72
83; DARWIN-NEXT:    .cfi_offset w26, -80
84; DARWIN-NEXT:    .cfi_offset w27, -88
85; DARWIN-NEXT:    .cfi_offset w28, -96
86; DARWIN-NEXT:    .cfi_offset b8, -104
87; DARWIN-NEXT:    .cfi_offset b9, -112
88; DARWIN-NEXT:    .cfi_offset b10, -120
89; DARWIN-NEXT:    .cfi_offset b11, -128
90; DARWIN-NEXT:    .cfi_offset b12, -136
91; DARWIN-NEXT:    .cfi_offset b13, -144
92; DARWIN-NEXT:    .cfi_offset b14, -152
93; DARWIN-NEXT:    .cfi_offset b15, -160
94; DARWIN-NEXT:    mov x20, x0
95; DARWIN-NEXT:    bl _callee
96; DARWIN-NEXT:    ldp x29, x30, [sp, #144] ; 16-byte Folded Reload
97; DARWIN-NEXT:    ldp x20, x19, [sp, #128] ; 16-byte Folded Reload
98; DARWIN-NEXT:    ldp x22, x21, [sp, #112] ; 16-byte Folded Reload
99; DARWIN-NEXT:    ldp x24, x23, [sp, #96] ; 16-byte Folded Reload
100; DARWIN-NEXT:    ldp x26, x25, [sp, #80] ; 16-byte Folded Reload
101; DARWIN-NEXT:    ldp x28, x27, [sp, #64] ; 16-byte Folded Reload
102; DARWIN-NEXT:    ldp d9, d8, [sp, #48] ; 16-byte Folded Reload
103; DARWIN-NEXT:    ldp d11, d10, [sp, #32] ; 16-byte Folded Reload
104; DARWIN-NEXT:    ldp d13, d12, [sp, #16] ; 16-byte Folded Reload
105; DARWIN-NEXT:    ldp d15, d14, [sp], #160 ; 16-byte Folded Reload
106; DARWIN-NEXT:    ret
107;
108; WIN-LABEL: caller1:
109; WIN:       .seh_proc caller1
110; WIN-NEXT:  // %bb.0:
111; WIN-NEXT:    stp x19, x20, [sp, #-160]! // 16-byte Folded Spill
112; WIN-NEXT:    .seh_save_regp_x x19, 160
113; WIN-NEXT:    stp x21, x22, [sp, #16] // 16-byte Folded Spill
114; WIN-NEXT:    .seh_save_regp x21, 16
115; WIN-NEXT:    stp x23, x24, [sp, #32] // 16-byte Folded Spill
116; WIN-NEXT:    .seh_save_regp x23, 32
117; WIN-NEXT:    stp x25, x26, [sp, #48] // 16-byte Folded Spill
118; WIN-NEXT:    .seh_save_regp x25, 48
119; WIN-NEXT:    stp x27, x28, [sp, #64] // 16-byte Folded Spill
120; WIN-NEXT:    .seh_save_regp x27, 64
121; WIN-NEXT:    str x30, [sp, #80] // 8-byte Folded Spill
122; WIN-NEXT:    .seh_save_reg x30, 80
123; WIN-NEXT:    stp d8, d9, [sp, #88] // 16-byte Folded Spill
124; WIN-NEXT:    .seh_save_fregp d8, 88
125; WIN-NEXT:    stp d10, d11, [sp, #104] // 16-byte Folded Spill
126; WIN-NEXT:    .seh_save_fregp d10, 104
127; WIN-NEXT:    stp d12, d13, [sp, #120] // 16-byte Folded Spill
128; WIN-NEXT:    .seh_save_fregp d12, 120
129; WIN-NEXT:    stp d14, d15, [sp, #136] // 16-byte Folded Spill
130; WIN-NEXT:    .seh_save_fregp d14, 136
131; WIN-NEXT:    .seh_endprologue
132; WIN-NEXT:    mov x20, x0
133; WIN-NEXT:    bl callee
134; WIN-NEXT:    .seh_startepilogue
135; WIN-NEXT:    ldp d14, d15, [sp, #136] // 16-byte Folded Reload
136; WIN-NEXT:    .seh_save_fregp d14, 136
137; WIN-NEXT:    ldp d12, d13, [sp, #120] // 16-byte Folded Reload
138; WIN-NEXT:    .seh_save_fregp d12, 120
139; WIN-NEXT:    ldp d10, d11, [sp, #104] // 16-byte Folded Reload
140; WIN-NEXT:    .seh_save_fregp d10, 104
141; WIN-NEXT:    ldp d8, d9, [sp, #88] // 16-byte Folded Reload
142; WIN-NEXT:    .seh_save_fregp d8, 88
143; WIN-NEXT:    ldr x30, [sp, #80] // 8-byte Folded Reload
144; WIN-NEXT:    .seh_save_reg x30, 80
145; WIN-NEXT:    ldp x27, x28, [sp, #64] // 16-byte Folded Reload
146; WIN-NEXT:    .seh_save_regp x27, 64
147; WIN-NEXT:    ldp x25, x26, [sp, #48] // 16-byte Folded Reload
148; WIN-NEXT:    .seh_save_regp x25, 48
149; WIN-NEXT:    ldp x23, x24, [sp, #32] // 16-byte Folded Reload
150; WIN-NEXT:    .seh_save_regp x23, 32
151; WIN-NEXT:    ldp x21, x22, [sp, #16] // 16-byte Folded Reload
152; WIN-NEXT:    .seh_save_regp x21, 16
153; WIN-NEXT:    ldp x19, x20, [sp], #160 // 16-byte Folded Reload
154; WIN-NEXT:    .seh_save_regp_x x19, 160
155; WIN-NEXT:    .seh_endepilogue
156; WIN-NEXT:    ret
157; WIN-NEXT:    .seh_endfunclet
158; WIN-NEXT:    .seh_endproc
159  tail call preserve_nonecc void @callee(ptr %a)
160  ret void
161}
162
163; Preserve_none caller calls preserve_none callee. Same function body.
164; The tail call is preserved. No registers are saved/restored around the call.
165; Actually a simple jmp instruction is generated.
166define preserve_nonecc void @caller2(ptr %a) {
167; CHECK-LABEL: caller2:
168; CHECK:       // %bb.0:
169; CHECK-NEXT:    b callee
170;
171; DARWIN-LABEL: caller2:
172; DARWIN:       ; %bb.0:
173; DARWIN-NEXT:    b _callee
174;
175; WIN-LABEL: caller2:
176; WIN:       // %bb.0:
177; WIN-NEXT:    b callee
178  tail call preserve_nonecc void @callee(ptr %a)
179  ret void
180}
181
182; Preserve_none function can use more registers to pass parameters.
183declare preserve_nonecc i64 @callee_with_many_param2(i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 %a12, i64 %a13, i64 %a14, i64 %a15, i64 %a16, i64 %a17, i64 %a18, i64 %a19, i64 %a20, i64 %a21, i64 %a22, i64 %a23, i64 %a24)
184define preserve_nonecc i64 @callee_with_many_param(i64 %a1, i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 %a12, i64 %a13, i64 %a14, i64 %a15, i64 %a16, i64 %a17, i64 %a18, i64 %a19, i64 %a20, i64 %a21, i64 %a22, i64 %a23, i64 %a24) {
185; CHECK-LABEL: callee_with_many_param:
186; CHECK:       // %bb.0:
187; CHECK-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
188; CHECK-NEXT:    .cfi_def_cfa_offset 16
189; CHECK-NEXT:    .cfi_offset w30, -16
190; CHECK-NEXT:    mov x8, x15
191; CHECK-NEXT:    mov x15, x20
192; CHECK-NEXT:    mov x20, x21
193; CHECK-NEXT:    mov x21, x22
194; CHECK-NEXT:    mov x22, x23
195; CHECK-NEXT:    mov x23, x24
196; CHECK-NEXT:    mov x24, x25
197; CHECK-NEXT:    mov x25, x26
198; CHECK-NEXT:    mov x26, x27
199; CHECK-NEXT:    mov x27, x28
200; CHECK-NEXT:    mov x28, x0
201; CHECK-NEXT:    mov x0, x1
202; CHECK-NEXT:    mov x1, x2
203; CHECK-NEXT:    mov x2, x3
204; CHECK-NEXT:    mov x3, x4
205; CHECK-NEXT:    mov x4, x5
206; CHECK-NEXT:    mov x5, x6
207; CHECK-NEXT:    mov x6, x7
208; CHECK-NEXT:    mov x7, x10
209; CHECK-NEXT:    mov x10, x11
210; CHECK-NEXT:    mov x11, x12
211; CHECK-NEXT:    mov x12, x13
212; CHECK-NEXT:    mov x13, x14
213; CHECK-NEXT:    mov x14, x9
214; CHECK-NEXT:    mov x9, x8
215; CHECK-NEXT:    bl callee_with_many_param2
216; CHECK-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
217; CHECK-NEXT:    ret
218;
219; DARWIN-LABEL: callee_with_many_param:
220; DARWIN:       ; %bb.0:
221; DARWIN-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
222; DARWIN-NEXT:    .cfi_def_cfa_offset 16
223; DARWIN-NEXT:    .cfi_offset w30, -8
224; DARWIN-NEXT:    .cfi_offset w29, -16
225; DARWIN-NEXT:    mov x8, x15
226; DARWIN-NEXT:    mov x15, x20
227; DARWIN-NEXT:    mov x20, x21
228; DARWIN-NEXT:    mov x21, x22
229; DARWIN-NEXT:    mov x22, x23
230; DARWIN-NEXT:    mov x23, x24
231; DARWIN-NEXT:    mov x24, x25
232; DARWIN-NEXT:    mov x25, x26
233; DARWIN-NEXT:    mov x26, x27
234; DARWIN-NEXT:    mov x27, x28
235; DARWIN-NEXT:    mov x28, x0
236; DARWIN-NEXT:    mov x0, x1
237; DARWIN-NEXT:    mov x1, x2
238; DARWIN-NEXT:    mov x2, x3
239; DARWIN-NEXT:    mov x3, x4
240; DARWIN-NEXT:    mov x4, x5
241; DARWIN-NEXT:    mov x5, x6
242; DARWIN-NEXT:    mov x6, x7
243; DARWIN-NEXT:    mov x7, x10
244; DARWIN-NEXT:    mov x10, x11
245; DARWIN-NEXT:    mov x11, x12
246; DARWIN-NEXT:    mov x12, x13
247; DARWIN-NEXT:    mov x13, x14
248; DARWIN-NEXT:    mov x14, x9
249; DARWIN-NEXT:    mov x9, x8
250; DARWIN-NEXT:    bl _callee_with_many_param2
251; DARWIN-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
252; DARWIN-NEXT:    ret
253;
254; WIN-LABEL: callee_with_many_param:
255; WIN:       .seh_proc callee_with_many_param
256; WIN-NEXT:  // %bb.0:
257; WIN-NEXT:    sub sp, sp, #32
258; WIN-NEXT:    .seh_stackalloc 32
259; WIN-NEXT:    str x30, [sp, #16] // 8-byte Folded Spill
260; WIN-NEXT:    .seh_save_reg x30, 16
261; WIN-NEXT:    .seh_endprologue
262; WIN-NEXT:    ldr x8, [sp, #32]
263; WIN-NEXT:    mov x15, x20
264; WIN-NEXT:    mov x20, x21
265; WIN-NEXT:    mov x21, x22
266; WIN-NEXT:    mov x22, x23
267; WIN-NEXT:    mov x23, x24
268; WIN-NEXT:    mov x24, x25
269; WIN-NEXT:    mov x25, x26
270; WIN-NEXT:    mov x26, x27
271; WIN-NEXT:    mov x27, x28
272; WIN-NEXT:    mov x28, x0
273; WIN-NEXT:    mov x0, x1
274; WIN-NEXT:    mov x1, x2
275; WIN-NEXT:    mov x2, x3
276; WIN-NEXT:    mov x3, x4
277; WIN-NEXT:    mov x4, x5
278; WIN-NEXT:    mov x5, x6
279; WIN-NEXT:    mov x6, x7
280; WIN-NEXT:    mov x7, x10
281; WIN-NEXT:    mov x10, x11
282; WIN-NEXT:    mov x11, x12
283; WIN-NEXT:    mov x12, x13
284; WIN-NEXT:    mov x13, x14
285; WIN-NEXT:    mov x14, x9
286; WIN-NEXT:    mov x9, x8
287; WIN-NEXT:    str x15, [sp]
288; WIN-NEXT:    bl callee_with_many_param2
289; WIN-NEXT:    .seh_startepilogue
290; WIN-NEXT:    ldr x30, [sp, #16] // 8-byte Folded Reload
291; WIN-NEXT:    .seh_save_reg x30, 16
292; WIN-NEXT:    add sp, sp, #32
293; WIN-NEXT:    .seh_stackalloc 32
294; WIN-NEXT:    .seh_endepilogue
295; WIN-NEXT:    ret
296; WIN-NEXT:    .seh_endfunclet
297; WIN-NEXT:    .seh_endproc
298  %ret = call preserve_nonecc i64 @callee_with_many_param2(i64 %a2, i64 %a3, i64 %a4, i64 %a5, i64 %a6, i64 %a7, i64 %a8, i64 %a9, i64 %a10, i64 %a11, i64 %a12, i64 %a13, i64 %a14, i64 %a15, i64 %a16, i64 %a17, i64 %a18, i64 %a19, i64 %a20, i64 %a21, i64 %a22, i64 %a23, i64 %a24, i64 %a1)
299  ret i64 %ret
300}
301
302define i64 @caller3() {
303; CHECK-LABEL: caller3:
304; CHECK:       // %bb.0:
305; CHECK-NEXT:    stp d15, d14, [sp, #-160]! // 16-byte Folded Spill
306; CHECK-NEXT:    stp d13, d12, [sp, #16] // 16-byte Folded Spill
307; CHECK-NEXT:    stp d11, d10, [sp, #32] // 16-byte Folded Spill
308; CHECK-NEXT:    stp d9, d8, [sp, #48] // 16-byte Folded Spill
309; CHECK-NEXT:    str x30, [sp, #64] // 8-byte Folded Spill
310; CHECK-NEXT:    stp x28, x27, [sp, #80] // 16-byte Folded Spill
311; CHECK-NEXT:    stp x26, x25, [sp, #96] // 16-byte Folded Spill
312; CHECK-NEXT:    stp x24, x23, [sp, #112] // 16-byte Folded Spill
313; CHECK-NEXT:    stp x22, x21, [sp, #128] // 16-byte Folded Spill
314; CHECK-NEXT:    stp x20, x19, [sp, #144] // 16-byte Folded Spill
315; CHECK-NEXT:    .cfi_def_cfa_offset 160
316; CHECK-NEXT:    .cfi_offset w19, -8
317; CHECK-NEXT:    .cfi_offset w20, -16
318; CHECK-NEXT:    .cfi_offset w21, -24
319; CHECK-NEXT:    .cfi_offset w22, -32
320; CHECK-NEXT:    .cfi_offset w23, -40
321; CHECK-NEXT:    .cfi_offset w24, -48
322; CHECK-NEXT:    .cfi_offset w25, -56
323; CHECK-NEXT:    .cfi_offset w26, -64
324; CHECK-NEXT:    .cfi_offset w27, -72
325; CHECK-NEXT:    .cfi_offset w28, -80
326; CHECK-NEXT:    .cfi_offset w30, -96
327; CHECK-NEXT:    .cfi_offset b8, -104
328; CHECK-NEXT:    .cfi_offset b9, -112
329; CHECK-NEXT:    .cfi_offset b10, -120
330; CHECK-NEXT:    .cfi_offset b11, -128
331; CHECK-NEXT:    .cfi_offset b12, -136
332; CHECK-NEXT:    .cfi_offset b13, -144
333; CHECK-NEXT:    .cfi_offset b14, -152
334; CHECK-NEXT:    .cfi_offset b15, -160
335; CHECK-NEXT:    mov w20, #1 // =0x1
336; CHECK-NEXT:    mov w21, #2 // =0x2
337; CHECK-NEXT:    mov w22, #3 // =0x3
338; CHECK-NEXT:    mov w23, #4 // =0x4
339; CHECK-NEXT:    mov w24, #5 // =0x5
340; CHECK-NEXT:    mov w25, #6 // =0x6
341; CHECK-NEXT:    mov w26, #7 // =0x7
342; CHECK-NEXT:    mov w27, #8 // =0x8
343; CHECK-NEXT:    mov w28, #9 // =0x9
344; CHECK-NEXT:    mov w0, #10 // =0xa
345; CHECK-NEXT:    mov w1, #11 // =0xb
346; CHECK-NEXT:    mov w2, #12 // =0xc
347; CHECK-NEXT:    mov w3, #13 // =0xd
348; CHECK-NEXT:    mov w4, #14 // =0xe
349; CHECK-NEXT:    mov w5, #15 // =0xf
350; CHECK-NEXT:    mov w6, #16 // =0x10
351; CHECK-NEXT:    mov w7, #17 // =0x11
352; CHECK-NEXT:    mov w10, #18 // =0x12
353; CHECK-NEXT:    mov w11, #19 // =0x13
354; CHECK-NEXT:    mov w12, #20 // =0x14
355; CHECK-NEXT:    mov w13, #21 // =0x15
356; CHECK-NEXT:    mov w14, #22 // =0x16
357; CHECK-NEXT:    mov w9, #23 // =0x17
358; CHECK-NEXT:    mov w15, #24 // =0x18
359; CHECK-NEXT:    bl callee_with_many_param
360; CHECK-NEXT:    ldp x20, x19, [sp, #144] // 16-byte Folded Reload
361; CHECK-NEXT:    ldr x30, [sp, #64] // 8-byte Folded Reload
362; CHECK-NEXT:    ldp x22, x21, [sp, #128] // 16-byte Folded Reload
363; CHECK-NEXT:    ldp x24, x23, [sp, #112] // 16-byte Folded Reload
364; CHECK-NEXT:    ldp x26, x25, [sp, #96] // 16-byte Folded Reload
365; CHECK-NEXT:    ldp x28, x27, [sp, #80] // 16-byte Folded Reload
366; CHECK-NEXT:    ldp d9, d8, [sp, #48] // 16-byte Folded Reload
367; CHECK-NEXT:    ldp d11, d10, [sp, #32] // 16-byte Folded Reload
368; CHECK-NEXT:    ldp d13, d12, [sp, #16] // 16-byte Folded Reload
369; CHECK-NEXT:    ldp d15, d14, [sp], #160 // 16-byte Folded Reload
370; CHECK-NEXT:    ret
371;
372; DARWIN-LABEL: caller3:
373; DARWIN:       ; %bb.0:
374; DARWIN-NEXT:    stp d15, d14, [sp, #-160]! ; 16-byte Folded Spill
375; DARWIN-NEXT:    stp d13, d12, [sp, #16] ; 16-byte Folded Spill
376; DARWIN-NEXT:    stp d11, d10, [sp, #32] ; 16-byte Folded Spill
377; DARWIN-NEXT:    stp d9, d8, [sp, #48] ; 16-byte Folded Spill
378; DARWIN-NEXT:    stp x28, x27, [sp, #64] ; 16-byte Folded Spill
379; DARWIN-NEXT:    stp x26, x25, [sp, #80] ; 16-byte Folded Spill
380; DARWIN-NEXT:    stp x24, x23, [sp, #96] ; 16-byte Folded Spill
381; DARWIN-NEXT:    stp x22, x21, [sp, #112] ; 16-byte Folded Spill
382; DARWIN-NEXT:    stp x20, x19, [sp, #128] ; 16-byte Folded Spill
383; DARWIN-NEXT:    stp x29, x30, [sp, #144] ; 16-byte Folded Spill
384; DARWIN-NEXT:    .cfi_def_cfa_offset 160
385; DARWIN-NEXT:    .cfi_offset w30, -8
386; DARWIN-NEXT:    .cfi_offset w29, -16
387; DARWIN-NEXT:    .cfi_offset w19, -24
388; DARWIN-NEXT:    .cfi_offset w20, -32
389; DARWIN-NEXT:    .cfi_offset w21, -40
390; DARWIN-NEXT:    .cfi_offset w22, -48
391; DARWIN-NEXT:    .cfi_offset w23, -56
392; DARWIN-NEXT:    .cfi_offset w24, -64
393; DARWIN-NEXT:    .cfi_offset w25, -72
394; DARWIN-NEXT:    .cfi_offset w26, -80
395; DARWIN-NEXT:    .cfi_offset w27, -88
396; DARWIN-NEXT:    .cfi_offset w28, -96
397; DARWIN-NEXT:    .cfi_offset b8, -104
398; DARWIN-NEXT:    .cfi_offset b9, -112
399; DARWIN-NEXT:    .cfi_offset b10, -120
400; DARWIN-NEXT:    .cfi_offset b11, -128
401; DARWIN-NEXT:    .cfi_offset b12, -136
402; DARWIN-NEXT:    .cfi_offset b13, -144
403; DARWIN-NEXT:    .cfi_offset b14, -152
404; DARWIN-NEXT:    .cfi_offset b15, -160
405; DARWIN-NEXT:    mov w20, #1 ; =0x1
406; DARWIN-NEXT:    mov w21, #2 ; =0x2
407; DARWIN-NEXT:    mov w22, #3 ; =0x3
408; DARWIN-NEXT:    mov w23, #4 ; =0x4
409; DARWIN-NEXT:    mov w24, #5 ; =0x5
410; DARWIN-NEXT:    mov w25, #6 ; =0x6
411; DARWIN-NEXT:    mov w26, #7 ; =0x7
412; DARWIN-NEXT:    mov w27, #8 ; =0x8
413; DARWIN-NEXT:    mov w28, #9 ; =0x9
414; DARWIN-NEXT:    mov w0, #10 ; =0xa
415; DARWIN-NEXT:    mov w1, #11 ; =0xb
416; DARWIN-NEXT:    mov w2, #12 ; =0xc
417; DARWIN-NEXT:    mov w3, #13 ; =0xd
418; DARWIN-NEXT:    mov w4, #14 ; =0xe
419; DARWIN-NEXT:    mov w5, #15 ; =0xf
420; DARWIN-NEXT:    mov w6, #16 ; =0x10
421; DARWIN-NEXT:    mov w7, #17 ; =0x11
422; DARWIN-NEXT:    mov w10, #18 ; =0x12
423; DARWIN-NEXT:    mov w11, #19 ; =0x13
424; DARWIN-NEXT:    mov w12, #20 ; =0x14
425; DARWIN-NEXT:    mov w13, #21 ; =0x15
426; DARWIN-NEXT:    mov w14, #22 ; =0x16
427; DARWIN-NEXT:    mov w9, #23 ; =0x17
428; DARWIN-NEXT:    mov w15, #24 ; =0x18
429; DARWIN-NEXT:    bl _callee_with_many_param
430; DARWIN-NEXT:    ldp x29, x30, [sp, #144] ; 16-byte Folded Reload
431; DARWIN-NEXT:    ldp x20, x19, [sp, #128] ; 16-byte Folded Reload
432; DARWIN-NEXT:    ldp x22, x21, [sp, #112] ; 16-byte Folded Reload
433; DARWIN-NEXT:    ldp x24, x23, [sp, #96] ; 16-byte Folded Reload
434; DARWIN-NEXT:    ldp x26, x25, [sp, #80] ; 16-byte Folded Reload
435; DARWIN-NEXT:    ldp x28, x27, [sp, #64] ; 16-byte Folded Reload
436; DARWIN-NEXT:    ldp d9, d8, [sp, #48] ; 16-byte Folded Reload
437; DARWIN-NEXT:    ldp d11, d10, [sp, #32] ; 16-byte Folded Reload
438; DARWIN-NEXT:    ldp d13, d12, [sp, #16] ; 16-byte Folded Reload
439; DARWIN-NEXT:    ldp d15, d14, [sp], #160 ; 16-byte Folded Reload
440; DARWIN-NEXT:    ret
441;
442; WIN-LABEL: caller3:
443; WIN:       .seh_proc caller3
444; WIN-NEXT:  // %bb.0:
445; WIN-NEXT:    sub sp, sp, #176
446; WIN-NEXT:    .seh_stackalloc 176
447; WIN-NEXT:    stp x19, x20, [sp, #16] // 16-byte Folded Spill
448; WIN-NEXT:    .seh_save_regp x19, 16
449; WIN-NEXT:    stp x21, x22, [sp, #32] // 16-byte Folded Spill
450; WIN-NEXT:    .seh_save_regp x21, 32
451; WIN-NEXT:    stp x23, x24, [sp, #48] // 16-byte Folded Spill
452; WIN-NEXT:    .seh_save_regp x23, 48
453; WIN-NEXT:    stp x25, x26, [sp, #64] // 16-byte Folded Spill
454; WIN-NEXT:    .seh_save_regp x25, 64
455; WIN-NEXT:    stp x27, x28, [sp, #80] // 16-byte Folded Spill
456; WIN-NEXT:    .seh_save_regp x27, 80
457; WIN-NEXT:    str x30, [sp, #96] // 8-byte Folded Spill
458; WIN-NEXT:    .seh_save_reg x30, 96
459; WIN-NEXT:    stp d8, d9, [sp, #104] // 16-byte Folded Spill
460; WIN-NEXT:    .seh_save_fregp d8, 104
461; WIN-NEXT:    stp d10, d11, [sp, #120] // 16-byte Folded Spill
462; WIN-NEXT:    .seh_save_fregp d10, 120
463; WIN-NEXT:    stp d12, d13, [sp, #136] // 16-byte Folded Spill
464; WIN-NEXT:    .seh_save_fregp d12, 136
465; WIN-NEXT:    stp d14, d15, [sp, #152] // 16-byte Folded Spill
466; WIN-NEXT:    .seh_save_fregp d14, 152
467; WIN-NEXT:    .seh_endprologue
468; WIN-NEXT:    mov w8, #24 // =0x18
469; WIN-NEXT:    mov w20, #1 // =0x1
470; WIN-NEXT:    mov w21, #2 // =0x2
471; WIN-NEXT:    mov w22, #3 // =0x3
472; WIN-NEXT:    mov w23, #4 // =0x4
473; WIN-NEXT:    mov w24, #5 // =0x5
474; WIN-NEXT:    mov w25, #6 // =0x6
475; WIN-NEXT:    mov w26, #7 // =0x7
476; WIN-NEXT:    mov w27, #8 // =0x8
477; WIN-NEXT:    mov w28, #9 // =0x9
478; WIN-NEXT:    mov w0, #10 // =0xa
479; WIN-NEXT:    mov w1, #11 // =0xb
480; WIN-NEXT:    mov w2, #12 // =0xc
481; WIN-NEXT:    mov w3, #13 // =0xd
482; WIN-NEXT:    mov w4, #14 // =0xe
483; WIN-NEXT:    mov w5, #15 // =0xf
484; WIN-NEXT:    mov w6, #16 // =0x10
485; WIN-NEXT:    mov w7, #17 // =0x11
486; WIN-NEXT:    mov w10, #18 // =0x12
487; WIN-NEXT:    mov w11, #19 // =0x13
488; WIN-NEXT:    mov w12, #20 // =0x14
489; WIN-NEXT:    mov w13, #21 // =0x15
490; WIN-NEXT:    mov w14, #22 // =0x16
491; WIN-NEXT:    mov w9, #23 // =0x17
492; WIN-NEXT:    str x8, [sp]
493; WIN-NEXT:    bl callee_with_many_param
494; WIN-NEXT:    .seh_startepilogue
495; WIN-NEXT:    ldp d14, d15, [sp, #152] // 16-byte Folded Reload
496; WIN-NEXT:    .seh_save_fregp d14, 152
497; WIN-NEXT:    ldp d12, d13, [sp, #136] // 16-byte Folded Reload
498; WIN-NEXT:    .seh_save_fregp d12, 136
499; WIN-NEXT:    ldp d10, d11, [sp, #120] // 16-byte Folded Reload
500; WIN-NEXT:    .seh_save_fregp d10, 120
501; WIN-NEXT:    ldp d8, d9, [sp, #104] // 16-byte Folded Reload
502; WIN-NEXT:    .seh_save_fregp d8, 104
503; WIN-NEXT:    ldr x30, [sp, #96] // 8-byte Folded Reload
504; WIN-NEXT:    .seh_save_reg x30, 96
505; WIN-NEXT:    ldp x27, x28, [sp, #80] // 16-byte Folded Reload
506; WIN-NEXT:    .seh_save_regp x27, 80
507; WIN-NEXT:    ldp x25, x26, [sp, #64] // 16-byte Folded Reload
508; WIN-NEXT:    .seh_save_regp x25, 64
509; WIN-NEXT:    ldp x23, x24, [sp, #48] // 16-byte Folded Reload
510; WIN-NEXT:    .seh_save_regp x23, 48
511; WIN-NEXT:    ldp x21, x22, [sp, #32] // 16-byte Folded Reload
512; WIN-NEXT:    .seh_save_regp x21, 32
513; WIN-NEXT:    ldp x19, x20, [sp, #16] // 16-byte Folded Reload
514; WIN-NEXT:    .seh_save_regp x19, 16
515; WIN-NEXT:    add sp, sp, #176
516; WIN-NEXT:    .seh_stackalloc 176
517; WIN-NEXT:    .seh_endepilogue
518; WIN-NEXT:    ret
519; WIN-NEXT:    .seh_endfunclet
520; WIN-NEXT:    .seh_endproc
521  %ret = call preserve_nonecc i64 @callee_with_many_param(i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15, i64 16, i64 17, i64 18, i64 19, i64 20, i64 21, i64 22, i64 23, i64 24)
522  ret i64 %ret
523}
524