xref: /llvm-project/llvm/test/CodeGen/X86/GlobalISel/callingconv.ll (revision 7b3bbd83c0c24087072ec5b22a76799ab31f87d5)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -enable-cse-in-irtranslator=0 -enable-cse-in-legalizer=0 -mtriple=i386-linux-gnu -mattr=+sse2  -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X32
3; RUN: llc -enable-cse-in-irtranslator=0 -enable-cse-in-legalizer=0 -mtriple=x86_64-linux-gnu             -global-isel -verify-machineinstrs < %s -o - | FileCheck %s --check-prefix=X64
4
5define i32 @test_ret_i32() {
6; X32-LABEL: test_ret_i32:
7; X32:       # %bb.0:
8; X32-NEXT:    movl $20, %eax
9; X32-NEXT:    retl
10;
11; X64-LABEL: test_ret_i32:
12; X64:       # %bb.0:
13; X64-NEXT:    movl $20, %eax
14; X64-NEXT:    retq
15  ret i32 20
16}
17
18define i64 @test_ret_i64() {
19; X32-LABEL: test_ret_i64:
20; X32:       # %bb.0:
21; X32-NEXT:    movl $-1, %eax
22; X32-NEXT:    movl $15, %edx
23; X32-NEXT:    retl
24;
25; X64-LABEL: test_ret_i64:
26; X64:       # %bb.0:
27; X64-NEXT:    movabsq $68719476735, %rax # imm = 0xFFFFFFFFF
28; X64-NEXT:    retq
29  ret i64 68719476735
30}
31
32define i8 @test_arg_i8(i8 %a) {
33; X32-LABEL: test_arg_i8:
34; X32:       # %bb.0:
35; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
36; X32-NEXT:    # kill: def $al killed $al killed $eax
37; X32-NEXT:    retl
38;
39; X64-LABEL: test_arg_i8:
40; X64:       # %bb.0:
41; X64-NEXT:    movl %edi, %eax
42; X64-NEXT:    # kill: def $al killed $al killed $eax
43; X64-NEXT:    retq
44  ret i8 %a
45}
46
47define i16 @test_arg_i16(i16 %a) {
48; X32-LABEL: test_arg_i16:
49; X32:       # %bb.0:
50; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
51; X32-NEXT:    # kill: def $ax killed $ax killed $eax
52; X32-NEXT:    retl
53;
54; X64-LABEL: test_arg_i16:
55; X64:       # %bb.0:
56; X64-NEXT:    movl %edi, %eax
57; X64-NEXT:    # kill: def $ax killed $ax killed $eax
58; X64-NEXT:    retq
59  ret i16 %a
60}
61
62define i32 @test_arg_i32(i32 %a) {
63; X32-LABEL: test_arg_i32:
64; X32:       # %bb.0:
65; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
66; X32-NEXT:    retl
67;
68; X64-LABEL: test_arg_i32:
69; X64:       # %bb.0:
70; X64-NEXT:    movl %edi, %eax
71; X64-NEXT:    retq
72  ret i32 %a
73}
74
75define i64 @test_arg_i64(i64 %a) {
76; X32-LABEL: test_arg_i64:
77; X32:       # %bb.0:
78; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
79; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
80; X32-NEXT:    retl
81;
82; X64-LABEL: test_arg_i64:
83; X64:       # %bb.0:
84; X64-NEXT:    movq %rdi, %rax
85; X64-NEXT:    retq
86  ret i64 %a
87}
88
89define i64 @test_i64_args_8(i64 %arg1, i64 %arg2, i64 %arg3, i64 %arg4, i64 %arg5, i64 %arg6, i64 %arg7, i64 %arg8) {
90; X32-LABEL: test_i64_args_8:
91; X32:       # %bb.0:
92; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
93; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
94; X32-NEXT:    retl
95;
96; X64-LABEL: test_i64_args_8:
97; X64:       # %bb.0:
98; X64-NEXT:    movq {{[0-9]+}}(%rsp), %rax
99; X64-NEXT:    retq
100  ret i64 %arg8
101}
102
103define <4 x i32> @test_v4i32_args(<4 x i32> %arg1, <4 x i32> %arg2) {
104; X32-LABEL: test_v4i32_args:
105; X32:       # %bb.0:
106; X32-NEXT:    movaps %xmm1, %xmm0
107; X32-NEXT:    retl
108;
109; X64-LABEL: test_v4i32_args:
110; X64:       # %bb.0:
111; X64-NEXT:    movaps %xmm1, %xmm0
112; X64-NEXT:    retq
113  ret <4 x i32> %arg2
114}
115
116define <8 x i32> @test_v8i32_args(<8 x i32> %arg1, <8 x i32> %arg2) {
117; X32-LABEL: test_v8i32_args:
118; X32:       # %bb.0:
119; X32-NEXT:    subl $12, %esp
120; X32-NEXT:    .cfi_def_cfa_offset 16
121; X32-NEXT:    movaps %xmm2, %xmm0
122; X32-NEXT:    movaps {{[0-9]+}}(%esp), %xmm1
123; X32-NEXT:    addl $12, %esp
124; X32-NEXT:    .cfi_def_cfa_offset 4
125; X32-NEXT:    retl
126;
127; X64-LABEL: test_v8i32_args:
128; X64:       # %bb.0:
129; X64-NEXT:    movaps %xmm2, %xmm0
130; X64-NEXT:    movaps %xmm3, %xmm1
131; X64-NEXT:    retq
132  ret <8 x i32> %arg2
133}
134
135declare void @trivial_callee()
136define void @test_trivial_call() {
137; X32-LABEL: test_trivial_call:
138; X32:       # %bb.0:
139; X32-NEXT:    subl $12, %esp
140; X32-NEXT:    .cfi_def_cfa_offset 16
141; X32-NEXT:    calll trivial_callee
142; X32-NEXT:    addl $12, %esp
143; X32-NEXT:    .cfi_def_cfa_offset 4
144; X32-NEXT:    retl
145;
146; X64-LABEL: test_trivial_call:
147; X64:       # %bb.0:
148; X64-NEXT:    pushq %rax
149; X64-NEXT:    .cfi_def_cfa_offset 16
150; X64-NEXT:    callq trivial_callee
151; X64-NEXT:    popq %rax
152; X64-NEXT:    .cfi_def_cfa_offset 8
153; X64-NEXT:    retq
154  call void @trivial_callee()
155  ret void
156}
157
158declare void @simple_arg_callee(i32 %in0, i32 %in1)
159define void @test_simple_arg_call(i32 %in0, i32 %in1) {
160; X32-LABEL: test_simple_arg_call:
161; X32:       # %bb.0:
162; X32-NEXT:    subl $12, %esp
163; X32-NEXT:    .cfi_def_cfa_offset 16
164; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
165; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
166; X32-NEXT:    movl %ecx, (%esp)
167; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
168; X32-NEXT:    calll simple_arg_callee
169; X32-NEXT:    addl $12, %esp
170; X32-NEXT:    .cfi_def_cfa_offset 4
171; X32-NEXT:    retl
172;
173; X64-LABEL: test_simple_arg_call:
174; X64:       # %bb.0:
175; X64-NEXT:    pushq %rax
176; X64-NEXT:    .cfi_def_cfa_offset 16
177; X64-NEXT:    movl %edi, %eax
178; X64-NEXT:    movl %esi, %edi
179; X64-NEXT:    movl %eax, %esi
180; X64-NEXT:    callq simple_arg_callee
181; X64-NEXT:    popq %rax
182; X64-NEXT:    .cfi_def_cfa_offset 8
183; X64-NEXT:    retq
184  call void @simple_arg_callee(i32 %in1, i32 %in0)
185  ret void
186}
187
188declare void @simple_arg8_callee(i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4, i32 %arg5, i32 %arg6, i32 %arg7, i32 %arg8)
189define void @test_simple_arg8_call(i32 %in0) {
190; X32-LABEL: test_simple_arg8_call:
191; X32:       # %bb.0:
192; X32-NEXT:    subl $44, %esp
193; X32-NEXT:    .cfi_def_cfa_offset 48
194; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
195; X32-NEXT:    movl %eax, (%esp)
196; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
197; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
198; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
199; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
200; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
201; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
202; X32-NEXT:    movl %eax, {{[0-9]+}}(%esp)
203; X32-NEXT:    calll simple_arg8_callee
204; X32-NEXT:    addl $44, %esp
205; X32-NEXT:    .cfi_def_cfa_offset 4
206; X32-NEXT:    retl
207;
208; X64-LABEL: test_simple_arg8_call:
209; X64:       # %bb.0:
210; X64-NEXT:    subq $24, %rsp
211; X64-NEXT:    .cfi_def_cfa_offset 32
212; X64-NEXT:    movl %edi, (%rsp)
213; X64-NEXT:    movl %edi, {{[0-9]+}}(%rsp)
214; X64-NEXT:    movl %edi, %esi
215; X64-NEXT:    movl %edi, %edx
216; X64-NEXT:    movl %edi, %ecx
217; X64-NEXT:    movl %edi, %r8d
218; X64-NEXT:    movl %edi, %r9d
219; X64-NEXT:    callq simple_arg8_callee
220; X64-NEXT:    addq $24, %rsp
221; X64-NEXT:    .cfi_def_cfa_offset 8
222; X64-NEXT:    retq
223  call void @simple_arg8_callee(i32 %in0, i32 %in0, i32 %in0, i32 %in0,i32 %in0, i32 %in0, i32 %in0, i32 %in0)
224  ret void
225}
226
227declare i32 @simple_return_callee(i32 %in0)
228define i32 @test_simple_return_callee() {
229; X32-LABEL: test_simple_return_callee:
230; X32:       # %bb.0:
231; X32-NEXT:    subl $12, %esp
232; X32-NEXT:    .cfi_def_cfa_offset 16
233; X32-NEXT:    movl $5, %eax
234; X32-NEXT:    movl %eax, (%esp)
235; X32-NEXT:    calll simple_return_callee
236; X32-NEXT:    addl %eax, %eax
237; X32-NEXT:    addl $12, %esp
238; X32-NEXT:    .cfi_def_cfa_offset 4
239; X32-NEXT:    retl
240;
241; X64-LABEL: test_simple_return_callee:
242; X64:       # %bb.0:
243; X64-NEXT:    pushq %rax
244; X64-NEXT:    .cfi_def_cfa_offset 16
245; X64-NEXT:    movl $5, %edi
246; X64-NEXT:    callq simple_return_callee
247; X64-NEXT:    addl %eax, %eax
248; X64-NEXT:    popq %rcx
249; X64-NEXT:    .cfi_def_cfa_offset 8
250; X64-NEXT:    retq
251  %call = call i32 @simple_return_callee(i32 5)
252  %r = add i32 %call, %call
253  ret i32 %r
254}
255
256declare <8 x i32> @split_return_callee(<8 x i32> %in0)
257define <8 x i32> @test_split_return_callee(<8 x i32> %arg1, <8 x i32> %arg2) {
258; X32-LABEL: test_split_return_callee:
259; X32:       # %bb.0:
260; X32-NEXT:    subl $44, %esp
261; X32-NEXT:    .cfi_def_cfa_offset 48
262; X32-NEXT:    movaps %xmm0, (%esp) # 16-byte Spill
263; X32-NEXT:    movaps %xmm1, {{[-0-9]+}}(%e{{[sb]}}p) # 16-byte Spill
264; X32-NEXT:    movdqa %xmm2, %xmm0
265; X32-NEXT:    movdqa {{[0-9]+}}(%esp), %xmm1
266; X32-NEXT:    calll split_return_callee
267; X32-NEXT:    paddd (%esp), %xmm0 # 16-byte Folded Reload
268; X32-NEXT:    paddd {{[-0-9]+}}(%e{{[sb]}}p), %xmm1 # 16-byte Folded Reload
269; X32-NEXT:    addl $44, %esp
270; X32-NEXT:    .cfi_def_cfa_offset 4
271; X32-NEXT:    retl
272;
273; X64-LABEL: test_split_return_callee:
274; X64:       # %bb.0:
275; X64-NEXT:    subq $40, %rsp
276; X64-NEXT:    .cfi_def_cfa_offset 48
277; X64-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
278; X64-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
279; X64-NEXT:    movdqa %xmm2, %xmm0
280; X64-NEXT:    movdqa %xmm3, %xmm1
281; X64-NEXT:    callq split_return_callee
282; X64-NEXT:    paddd (%rsp), %xmm0 # 16-byte Folded Reload
283; X64-NEXT:    paddd {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Folded Reload
284; X64-NEXT:    addq $40, %rsp
285; X64-NEXT:    .cfi_def_cfa_offset 8
286; X64-NEXT:    retq
287  %call = call <8 x i32> @split_return_callee(<8 x i32> %arg2)
288  %r = add <8 x i32> %arg1, %call
289  ret  <8 x i32> %r
290}
291
292define void @test_indirect_call(ptr %func) {
293; X32-LABEL: test_indirect_call:
294; X32:       # %bb.0:
295; X32-NEXT:    subl $12, %esp
296; X32-NEXT:    .cfi_def_cfa_offset 16
297; X32-NEXT:    calll *{{[0-9]+}}(%esp)
298; X32-NEXT:    addl $12, %esp
299; X32-NEXT:    .cfi_def_cfa_offset 4
300; X32-NEXT:    retl
301;
302; X64-LABEL: test_indirect_call:
303; X64:       # %bb.0:
304; X64-NEXT:    pushq %rax
305; X64-NEXT:    .cfi_def_cfa_offset 16
306; X64-NEXT:    callq *%rdi
307; X64-NEXT:    popq %rax
308; X64-NEXT:    .cfi_def_cfa_offset 8
309; X64-NEXT:    retq
310  call void %func()
311  ret void
312}
313
314declare void @take_char(i8)
315define void @test_abi_exts_call(ptr %addr) {
316; X32-LABEL: test_abi_exts_call:
317; X32:       # %bb.0:
318; X32-NEXT:    pushl %ebx
319; X32-NEXT:    .cfi_def_cfa_offset 8
320; X32-NEXT:    pushl %esi
321; X32-NEXT:    .cfi_def_cfa_offset 12
322; X32-NEXT:    pushl %eax
323; X32-NEXT:    .cfi_def_cfa_offset 16
324; X32-NEXT:    .cfi_offset %esi, -12
325; X32-NEXT:    .cfi_offset %ebx, -8
326; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
327; X32-NEXT:    movzbl (%eax), %ebx
328; X32-NEXT:    movzbl %bl, %esi
329; X32-NEXT:    movl %esi, (%esp)
330; X32-NEXT:    calll take_char
331; X32-NEXT:    movsbl %bl, %eax
332; X32-NEXT:    movl %eax, (%esp)
333; X32-NEXT:    calll take_char
334; X32-NEXT:    movl %esi, (%esp)
335; X32-NEXT:    calll take_char
336; X32-NEXT:    addl $4, %esp
337; X32-NEXT:    .cfi_def_cfa_offset 12
338; X32-NEXT:    popl %esi
339; X32-NEXT:    .cfi_def_cfa_offset 8
340; X32-NEXT:    popl %ebx
341; X32-NEXT:    .cfi_def_cfa_offset 4
342; X32-NEXT:    retl
343;
344; X64-LABEL: test_abi_exts_call:
345; X64:       # %bb.0:
346; X64-NEXT:    pushq %rbx
347; X64-NEXT:    .cfi_def_cfa_offset 16
348; X64-NEXT:    .cfi_offset %rbx, -16
349; X64-NEXT:    movzbl (%rdi), %eax
350; X64-NEXT:    movzbl %al, %ebx
351; X64-NEXT:    movl %ebx, %edi
352; X64-NEXT:    callq take_char
353; X64-NEXT:    movsbl %bl, %edi
354; X64-NEXT:    callq take_char
355; X64-NEXT:    movl %ebx, %edi
356; X64-NEXT:    callq take_char
357; X64-NEXT:    popq %rbx
358; X64-NEXT:    .cfi_def_cfa_offset 8
359; X64-NEXT:    retq
360  %val = load i8, ptr %addr
361  call void @take_char(i8 %val)
362  call void @take_char(i8 signext %val)
363  call void @take_char(i8 zeroext %val)
364 ret void
365}
366
367declare void @variadic_callee(ptr, ...)
368define void @test_variadic_call_1(ptr %addr_ptr, ptr %val_ptr) {
369; X32-LABEL: test_variadic_call_1:
370; X32:       # %bb.0:
371; X32-NEXT:    subl $12, %esp
372; X32-NEXT:    .cfi_def_cfa_offset 16
373; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
374; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
375; X32-NEXT:    movl (%eax), %eax
376; X32-NEXT:    movl (%ecx), %ecx
377; X32-NEXT:    movl %eax, (%esp)
378; X32-NEXT:    movl %ecx, {{[0-9]+}}(%esp)
379; X32-NEXT:    calll variadic_callee
380; X32-NEXT:    addl $12, %esp
381; X32-NEXT:    .cfi_def_cfa_offset 4
382; X32-NEXT:    retl
383;
384; X64-LABEL: test_variadic_call_1:
385; X64:       # %bb.0:
386; X64-NEXT:    pushq %rax
387; X64-NEXT:    .cfi_def_cfa_offset 16
388; X64-NEXT:    movq (%rdi), %rdi
389; X64-NEXT:    movl (%rsi), %esi
390; X64-NEXT:    movb $0, %al
391; X64-NEXT:    callq variadic_callee
392; X64-NEXT:    popq %rax
393; X64-NEXT:    .cfi_def_cfa_offset 8
394; X64-NEXT:    retq
395
396  %addr = load ptr, ptr %addr_ptr
397  %val = load i32, ptr %val_ptr
398  call void (ptr, ...) @variadic_callee(ptr %addr, i32 %val)
399  ret void
400}
401
402define void @test_variadic_call_2(ptr %addr_ptr, ptr %val_ptr) {
403; X32-LABEL: test_variadic_call_2:
404; X32:       # %bb.0:
405; X32-NEXT:    subl $12, %esp
406; X32-NEXT:    .cfi_def_cfa_offset 16
407; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
408; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
409; X32-NEXT:    movl (%eax), %eax
410; X32-NEXT:    movl (%ecx), %edx
411; X32-NEXT:    movl 4(%ecx), %ecx
412; X32-NEXT:    movl %eax, (%esp)
413; X32-NEXT:    movl $4, %eax
414; X32-NEXT:    addl %esp, %eax
415; X32-NEXT:    movl %edx, {{[0-9]+}}(%esp)
416; X32-NEXT:    movl %ecx, 4(%eax)
417; X32-NEXT:    calll variadic_callee
418; X32-NEXT:    addl $12, %esp
419; X32-NEXT:    .cfi_def_cfa_offset 4
420; X32-NEXT:    retl
421;
422; X64-LABEL: test_variadic_call_2:
423; X64:       # %bb.0:
424; X64-NEXT:    pushq %rax
425; X64-NEXT:    .cfi_def_cfa_offset 16
426; X64-NEXT:    movq (%rdi), %rdi
427; X64-NEXT:    movq (%rsi), %rax
428; X64-NEXT:    movq %rax, %xmm0
429; X64-NEXT:    movb $1, %al
430; X64-NEXT:    callq variadic_callee
431; X64-NEXT:    popq %rax
432; X64-NEXT:    .cfi_def_cfa_offset 8
433; X64-NEXT:    retq
434
435  %addr = load ptr, ptr %addr_ptr
436  %val = load double, ptr %val_ptr
437  call void (ptr, ...) @variadic_callee(ptr %addr, double %val)
438  ret void
439}
440