Skip to content

Commit e5b01ef

Browse files
committed
add x32 and x64 musttail byval tests
1 parent e5dbe7b commit e5b01ef

File tree

1 file changed

+203
-70
lines changed

1 file changed

+203
-70
lines changed

llvm/test/CodeGen/X86/musttail-struct.ll

Lines changed: 203 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2-
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -x86-asm-syntax=intel | FileCheck %s
2+
; RUN: llc < %s -mtriple=i686-unknown-unknown -x86-asm-syntax=intel | FileCheck %s --check-prefix=X32
3+
; RUN: llc < %s -mtriple=x86_64-unknown-unknown -x86-asm-syntax=intel | FileCheck %s --check-prefix=X64
34

45
; Test correct handling of a musttail call with a byval struct argument.
56

@@ -13,54 +14,80 @@ declare dso_local i32 @Func5(ptr byval(%struct.5xi32) %0)
1314
declare dso_local i32 @FuncManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
1415

1516
define dso_local i32 @test1(ptr byval(%struct.1xi32) %0) {
16-
; CHECK-LABEL: test1:
17-
; CHECK: # %bb.0:
18-
; CHECK-NEXT: jmp Func1 # TAILCALL
17+
; X32-LABEL: test1:
18+
; X32: # %bb.0:
19+
; X32-NEXT: jmp Func1 # TAILCALL
20+
;
21+
; X64-LABEL: test1:
22+
; X64: # %bb.0:
23+
; X64-NEXT: jmp Func1 # TAILCALL
1924
%r = musttail call i32 @Func1(ptr byval(%struct.1xi32) %0)
2025
ret i32 %r
2126
}
2227

2328
define dso_local i32 @test3(ptr byval(%struct.3xi32) %0) {
24-
; CHECK-LABEL: test3:
25-
; CHECK: # %bb.0:
26-
; CHECK-NEXT: jmp Func3 # TAILCALL
29+
; X32-LABEL: test3:
30+
; X32: # %bb.0:
31+
; X32-NEXT: jmp Func3 # TAILCALL
32+
;
33+
; X64-LABEL: test3:
34+
; X64: # %bb.0:
35+
; X64-NEXT: jmp Func3 # TAILCALL
2736
%r = musttail call i32 @Func3(ptr byval(%struct.3xi32) %0)
2837
ret i32 %r
2938
}
3039

3140
; sizeof(%struct.5xi32) > 16, in x64 this is passed on stack.
3241
define dso_local i32 @test5(ptr byval(%struct.5xi32) %0) {
33-
; CHECK-LABEL: test5:
34-
; CHECK: # %bb.0:
35-
; CHECK-NEXT: jmp Func5 # TAILCALL
42+
; X32-LABEL: test5:
43+
; X32: # %bb.0:
44+
; X32-NEXT: jmp Func5 # TAILCALL
45+
;
46+
; X64-LABEL: test5:
47+
; X64: # %bb.0:
48+
; X64-NEXT: jmp Func5 # TAILCALL
3649
%r = musttail call i32 @Func5(ptr byval(%struct.5xi32) %0)
3750
ret i32 %r
3851
}
3952

4053
; Test passing multiple arguments with different sizes on stack. In x64 Linux
4154
; the first 6 are passed by register.
4255
define dso_local i32 @testManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7) {
43-
; CHECK-LABEL: testManyArgs:
44-
; CHECK: # %bb.0:
45-
; CHECK-NEXT: jmp FuncManyArgs # TAILCALL
56+
; X32-LABEL: testManyArgs:
57+
; X32: # %bb.0:
58+
; X32-NEXT: jmp FuncManyArgs # TAILCALL
59+
;
60+
; X64-LABEL: testManyArgs:
61+
; X64: # %bb.0:
62+
; X64-NEXT: jmp FuncManyArgs # TAILCALL
4663
%r = musttail call i32 @FuncManyArgs(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
4764
ret i32 %r
4865
}
4966

5067
define dso_local i32 @testRecursion(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7) {
51-
; CHECK-LABEL: testRecursion:
52-
; CHECK: # %bb.0:
53-
; CHECK-NEXT: jmp testRecursion # TAILCALL
68+
; X32-LABEL: testRecursion:
69+
; X32: # %bb.0:
70+
; X32-NEXT: jmp testRecursion # TAILCALL
71+
;
72+
; X64-LABEL: testRecursion:
73+
; X64: # %bb.0:
74+
; X64-NEXT: jmp testRecursion # TAILCALL
5475
%r = musttail call i32 @testRecursion(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4, i32 %5, i8 %6, ptr byval(%struct.5xi32) %7)
5576
ret i32 %r
5677
}
5778

5879
define dso_local i32 @swap(ptr byval(%struct.1xi32) %0, ptr byval(%struct.1xi32) %1) noinline {
59-
; CHECK-LABEL: swap:
60-
; CHECK: # %bb.0: # %entry
61-
; CHECK-NEXT: mov eax, dword ptr [rsp + 8]
62-
; CHECK-NEXT: add eax, dword ptr [rsp + 16]
63-
; CHECK-NEXT: ret
80+
; X32-LABEL: swap:
81+
; X32: # %bb.0: # %entry
82+
; X32-NEXT: mov eax, dword ptr [esp + 4]
83+
; X32-NEXT: add eax, dword ptr [esp + 8]
84+
; X32-NEXT: ret
85+
;
86+
; X64-LABEL: swap:
87+
; X64: # %bb.0: # %entry
88+
; X64-NEXT: mov eax, dword ptr [rsp + 8]
89+
; X64-NEXT: add eax, dword ptr [rsp + 16]
90+
; X64-NEXT: ret
6491
entry:
6592
%a.ptr = getelementptr inbounds %struct.1xi32, ptr %0, i32 0, i32 0, i32 0
6693
%a = load i32, ptr %a.ptr, align 4
@@ -71,15 +98,25 @@ entry:
7198
}
7299

73100
define dso_local i32 @swapByValArguments(ptr byval(%struct.1xi32) %0, ptr byval(%struct.1xi32) %1) {
74-
; CHECK-LABEL: swapByValArguments:
75-
; CHECK: # %bb.0:
76-
; CHECK-NEXT: mov eax, dword ptr [rsp + 8]
77-
; CHECK-NEXT: mov dword ptr [rsp - 16], eax
78-
; CHECK-NEXT: mov eax, dword ptr [rsp + 16]
79-
; CHECK-NEXT: mov dword ptr [rsp - 8], eax
80-
; CHECK-NEXT: jmp swap # TAILCALL
81-
82-
101+
; X32-LABEL: swapByValArguments:
102+
; X32: # %bb.0:
103+
; X32-NEXT: sub esp, 8
104+
; X32-NEXT: .cfi_def_cfa_offset 12
105+
; X32-NEXT: mov eax, dword ptr [esp + 12]
106+
; X32-NEXT: mov dword ptr [esp], eax
107+
; X32-NEXT: mov eax, dword ptr [esp + 16]
108+
; X32-NEXT: mov dword ptr [esp + 4], eax
109+
; X32-NEXT: add esp, 8
110+
; X32-NEXT: .cfi_def_cfa_offset 4
111+
; X32-NEXT: jmp swap # TAILCALL
112+
;
113+
; X64-LABEL: swapByValArguments:
114+
; X64: # %bb.0:
115+
; X64-NEXT: mov eax, dword ptr [rsp + 8]
116+
; X64-NEXT: mov dword ptr [rsp - 16], eax
117+
; X64-NEXT: mov eax, dword ptr [rsp + 16]
118+
; X64-NEXT: mov dword ptr [rsp - 8], eax
119+
; X64-NEXT: jmp swap # TAILCALL
83120
%r = musttail call i32 @swap(ptr byval(%struct.1xi32) %1, ptr byval(%struct.1xi32) %0)
84121
ret i32 %r
85122
}
@@ -94,9 +131,13 @@ declare void @large_callee(%twenty_bytes* byval(%twenty_bytes) align 4)
94131
; actually passed in registers and the stack in the same way for the caller and
95132
; callee. On x86 byval arguments are never (partially) passed via registers.
96133
define void @large_caller(%twenty_bytes* byval(%twenty_bytes) align 4 %a) {
97-
; CHECK-LABEL: large_caller:
98-
; CHECK: # %bb.0: # %entry
99-
; CHECK-NEXT: jmp large_callee@PLT # TAILCALL
134+
; X32-LABEL: large_caller:
135+
; X32: # %bb.0: # %entry
136+
; X32-NEXT: jmp large_callee@PLT # TAILCALL
137+
;
138+
; X64-LABEL: large_caller:
139+
; X64: # %bb.0: # %entry
140+
; X64-NEXT: jmp large_callee@PLT # TAILCALL
100141
entry:
101142
musttail call void @large_callee(%twenty_bytes* byval(%twenty_bytes) align 4 %a)
102143
ret void
@@ -107,17 +148,35 @@ entry:
107148
; into the stack space allocated by @large_caller_new_value's caller, so is
108149
; valid.
109150
define void @large_caller_new_value(%twenty_bytes* byval(%twenty_bytes) align 4 %a) {
110-
; CHECK-LABEL: large_caller_new_value:
111-
; CHECK: # %bb.0: # %entry
112-
; CHECK-NEXT: movabs rax, 4294967296
113-
; CHECK-NEXT: mov qword ptr [rsp - 20], rax
114-
; CHECK-NEXT: movabs rcx, 12884901890
115-
; CHECK-NEXT: mov qword ptr [rsp - 12], rcx
116-
; CHECK-NEXT: mov dword ptr [rsp - 4], 4
117-
; CHECK-NEXT: mov qword ptr [rsp + 8], rax
118-
; CHECK-NEXT: mov qword ptr [rsp + 16], rcx
119-
; CHECK-NEXT: mov dword ptr [rsp + 24], 4
120-
; CHECK-NEXT: jmp large_callee@PLT # TAILCALL
151+
; X32-LABEL: large_caller_new_value:
152+
; X32: # %bb.0: # %entry
153+
; X32-NEXT: sub esp, 20
154+
; X32-NEXT: .cfi_def_cfa_offset 24
155+
; X32-NEXT: mov dword ptr [esp], 0
156+
; X32-NEXT: mov dword ptr [esp + 4], 1
157+
; X32-NEXT: mov dword ptr [esp + 8], 2
158+
; X32-NEXT: mov dword ptr [esp + 12], 3
159+
; X32-NEXT: mov dword ptr [esp + 16], 4
160+
; X32-NEXT: mov dword ptr [esp + 24], 0
161+
; X32-NEXT: mov dword ptr [esp + 28], 1
162+
; X32-NEXT: mov dword ptr [esp + 32], 2
163+
; X32-NEXT: mov dword ptr [esp + 36], 3
164+
; X32-NEXT: mov dword ptr [esp + 40], 4
165+
; X32-NEXT: add esp, 20
166+
; X32-NEXT: .cfi_def_cfa_offset 4
167+
; X32-NEXT: jmp large_callee@PLT # TAILCALL
168+
;
169+
; X64-LABEL: large_caller_new_value:
170+
; X64: # %bb.0: # %entry
171+
; X64-NEXT: movabs rax, 4294967296
172+
; X64-NEXT: mov qword ptr [rsp - 20], rax
173+
; X64-NEXT: movabs rcx, 12884901890
174+
; X64-NEXT: mov qword ptr [rsp - 12], rcx
175+
; X64-NEXT: mov dword ptr [rsp - 4], 4
176+
; X64-NEXT: mov qword ptr [rsp + 8], rax
177+
; X64-NEXT: mov qword ptr [rsp + 16], rcx
178+
; X64-NEXT: mov dword ptr [rsp + 24], 4
179+
; X64-NEXT: jmp large_callee@PLT # TAILCALL
121180
entry:
122181
%y = alloca %twenty_bytes, align 4
123182
store i32 0, ptr %y, align 4
@@ -135,19 +194,47 @@ entry:
135194

136195
declare void @two_byvals_callee(%twenty_bytes* byval(%twenty_bytes) align 4, %twenty_bytes* byval(%twenty_bytes) align 4)
137196
define void @swap_byvals(%twenty_bytes* byval(%twenty_bytes) align 4 %a, %twenty_bytes* byval(%twenty_bytes) align 4 %b) {
138-
; CHECK-LABEL: swap_byvals:
139-
; CHECK: # %bb.0: # %entry
140-
; CHECK-NEXT: mov eax, dword ptr [rsp + 24]
141-
; CHECK-NEXT: mov dword ptr [rsp - 8], eax
142-
; CHECK-NEXT: movaps xmm0, xmmword ptr [rsp + 8]
143-
; CHECK-NEXT: movaps xmmword ptr [rsp - 24], xmm0
144-
; CHECK-NEXT: mov eax, dword ptr [rsp + 48]
145-
; CHECK-NEXT: mov dword ptr [rsp - 32], eax
146-
; CHECK-NEXT: mov rax, qword ptr [rsp + 32]
147-
; CHECK-NEXT: mov rcx, qword ptr [rsp + 40]
148-
; CHECK-NEXT: mov qword ptr [rsp - 40], rcx
149-
; CHECK-NEXT: mov qword ptr [rsp - 48], rax
150-
; CHECK-NEXT: jmp two_byvals_callee@PLT # TAILCALL
197+
; X32-LABEL: swap_byvals:
198+
; X32: # %bb.0: # %entry
199+
; X32-NEXT: sub esp, 40
200+
; X32-NEXT: .cfi_def_cfa_offset 44
201+
; X32-NEXT: mov eax, dword ptr [esp + 60]
202+
; X32-NEXT: mov dword ptr [esp + 16], eax
203+
; X32-NEXT: mov eax, dword ptr [esp + 56]
204+
; X32-NEXT: mov dword ptr [esp + 12], eax
205+
; X32-NEXT: mov eax, dword ptr [esp + 52]
206+
; X32-NEXT: mov dword ptr [esp + 8], eax
207+
; X32-NEXT: mov eax, dword ptr [esp + 44]
208+
; X32-NEXT: mov ecx, dword ptr [esp + 48]
209+
; X32-NEXT: mov dword ptr [esp + 4], ecx
210+
; X32-NEXT: mov dword ptr [esp], eax
211+
; X32-NEXT: mov eax, dword ptr [esp + 80]
212+
; X32-NEXT: mov dword ptr [esp + 36], eax
213+
; X32-NEXT: mov eax, dword ptr [esp + 76]
214+
; X32-NEXT: mov dword ptr [esp + 32], eax
215+
; X32-NEXT: mov eax, dword ptr [esp + 72]
216+
; X32-NEXT: mov dword ptr [esp + 28], eax
217+
; X32-NEXT: mov eax, dword ptr [esp + 64]
218+
; X32-NEXT: mov ecx, dword ptr [esp + 68]
219+
; X32-NEXT: mov dword ptr [esp + 24], ecx
220+
; X32-NEXT: mov dword ptr [esp + 20], eax
221+
; X32-NEXT: add esp, 40
222+
; X32-NEXT: .cfi_def_cfa_offset 4
223+
; X32-NEXT: jmp two_byvals_callee@PLT # TAILCALL
224+
;
225+
; X64-LABEL: swap_byvals:
226+
; X64: # %bb.0: # %entry
227+
; X64-NEXT: mov eax, dword ptr [rsp + 24]
228+
; X64-NEXT: mov dword ptr [rsp - 8], eax
229+
; X64-NEXT: movaps xmm0, xmmword ptr [rsp + 8]
230+
; X64-NEXT: movaps xmmword ptr [rsp - 24], xmm0
231+
; X64-NEXT: mov eax, dword ptr [rsp + 48]
232+
; X64-NEXT: mov dword ptr [rsp - 32], eax
233+
; X64-NEXT: mov rax, qword ptr [rsp + 32]
234+
; X64-NEXT: mov rcx, qword ptr [rsp + 40]
235+
; X64-NEXT: mov qword ptr [rsp - 40], rcx
236+
; X64-NEXT: mov qword ptr [rsp - 48], rax
237+
; X64-NEXT: jmp two_byvals_callee@PLT # TAILCALL
151238
entry:
152239
musttail call void @two_byvals_callee(%twenty_bytes* byval(%twenty_bytes) align 4 %b, %twenty_bytes* byval(%twenty_bytes) align 4 %a)
153240
ret void
@@ -159,9 +246,41 @@ entry:
159246
; can be tail-call optimized.
160247
declare void @shift_byval_callee(%twenty_bytes* byval(%twenty_bytes) align 4)
161248
define void @shift_byval(i32 %a, %twenty_bytes* byval(%twenty_bytes) align 4 %b) {
162-
; CHECK-LABEL: shift_byval:
163-
; CHECK: # %bb.0: # %entry
164-
; CHECK-NEXT: jmp shift_byval_callee@PLT # TAILCALL
249+
; X32-LABEL: shift_byval:
250+
; X32: # %bb.0: # %entry
251+
; X32-NEXT: push edi
252+
; X32-NEXT: .cfi_def_cfa_offset 8
253+
; X32-NEXT: push esi
254+
; X32-NEXT: .cfi_def_cfa_offset 12
255+
; X32-NEXT: .cfi_offset esi, -12
256+
; X32-NEXT: .cfi_offset edi, -8
257+
; X32-NEXT: mov eax, dword ptr [esp + 32]
258+
; X32-NEXT: mov ecx, dword ptr [esp + 28]
259+
; X32-NEXT: mov edx, dword ptr [esp + 24]
260+
; X32-NEXT: mov esi, dword ptr [esp + 16]
261+
; X32-NEXT: mov edi, dword ptr [esp + 20]
262+
; X32-NEXT: push eax
263+
; X32-NEXT: .cfi_adjust_cfa_offset 4
264+
; X32-NEXT: push ecx
265+
; X32-NEXT: .cfi_adjust_cfa_offset 4
266+
; X32-NEXT: push edx
267+
; X32-NEXT: .cfi_adjust_cfa_offset 4
268+
; X32-NEXT: push edi
269+
; X32-NEXT: .cfi_adjust_cfa_offset 4
270+
; X32-NEXT: push esi
271+
; X32-NEXT: .cfi_adjust_cfa_offset 4
272+
; X32-NEXT: call shift_byval_callee@PLT
273+
; X32-NEXT: add esp, 20
274+
; X32-NEXT: .cfi_adjust_cfa_offset -20
275+
; X32-NEXT: pop esi
276+
; X32-NEXT: .cfi_def_cfa_offset 8
277+
; X32-NEXT: pop edi
278+
; X32-NEXT: .cfi_def_cfa_offset 4
279+
; X32-NEXT: ret
280+
;
281+
; X64-LABEL: shift_byval:
282+
; X64: # %bb.0: # %entry
283+
; X64-NEXT: jmp shift_byval_callee@PLT # TAILCALL
165284
entry:
166285
tail call void @shift_byval_callee(%twenty_bytes* byval(%twenty_bytes) align 4 %b)
167286
ret void
@@ -171,16 +290,30 @@ entry:
171290
; need a stack temporary.
172291
@large_global = external global %twenty_bytes
173292
define void @large_caller_from_global(%twenty_bytes* byval(%twenty_bytes) align 4 %a) {
174-
; CHECK-LABEL: large_caller_from_global:
175-
; CHECK: # %bb.0: # %entry
176-
; CHECK-NEXT: mov rax, qword ptr [rip + large_global@GOTPCREL]
177-
; CHECK-NEXT: mov ecx, dword ptr [rax + 16]
178-
; CHECK-NEXT: mov dword ptr [rsp + 24], ecx
179-
; CHECK-NEXT: mov rcx, qword ptr [rax]
180-
; CHECK-NEXT: mov rax, qword ptr [rax + 8]
181-
; CHECK-NEXT: mov qword ptr [rsp + 16], rax
182-
; CHECK-NEXT: mov qword ptr [rsp + 8], rcx
183-
; CHECK-NEXT: jmp large_callee@PLT # TAILCALL
293+
; X32-LABEL: large_caller_from_global:
294+
; X32: # %bb.0: # %entry
295+
; X32-NEXT: mov eax, dword ptr [large_global+16]
296+
; X32-NEXT: mov dword ptr [esp + 20], eax
297+
; X32-NEXT: mov eax, dword ptr [large_global+12]
298+
; X32-NEXT: mov dword ptr [esp + 16], eax
299+
; X32-NEXT: mov eax, dword ptr [large_global+8]
300+
; X32-NEXT: mov dword ptr [esp + 12], eax
301+
; X32-NEXT: mov eax, dword ptr [large_global+4]
302+
; X32-NEXT: mov dword ptr [esp + 8], eax
303+
; X32-NEXT: mov eax, dword ptr [large_global]
304+
; X32-NEXT: mov dword ptr [esp + 4], eax
305+
; X32-NEXT: jmp large_callee@PLT # TAILCALL
306+
;
307+
; X64-LABEL: large_caller_from_global:
308+
; X64: # %bb.0: # %entry
309+
; X64-NEXT: mov rax, qword ptr [rip + large_global@GOTPCREL]
310+
; X64-NEXT: mov ecx, dword ptr [rax + 16]
311+
; X64-NEXT: mov dword ptr [rsp + 24], ecx
312+
; X64-NEXT: mov rcx, qword ptr [rax]
313+
; X64-NEXT: mov rax, qword ptr [rax + 8]
314+
; X64-NEXT: mov qword ptr [rsp + 16], rax
315+
; X64-NEXT: mov qword ptr [rsp + 8], rcx
316+
; X64-NEXT: jmp large_callee@PLT # TAILCALL
184317
entry:
185318
musttail call void @large_callee(%twenty_bytes* byval(%twenty_bytes) align 4 @large_global)
186319
ret void

0 commit comments

Comments
 (0)