xref: /llvm-project/llvm/test/CodeGen/X86/tailcall-msvc-conventions.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; RUN: llc -mtriple=i686-unknown-linux-gnu -O1 < %s | FileCheck %s
2; RUN: llc -mtriple=i686-unknown-linux-gnu -O0 < %s | FileCheck %s
3
4; The MSVC family of x86 calling conventions makes tail calls really tricky.
5; Tests of all the various combinations should live here.
6
7declare i32 @cdecl_i32()
8declare void @cdecl_void()
9
10; Don't allow tail calling these cdecl functions, because we need to clear the
11; incoming stack arguments for these argument-clearing conventions.
12
13define x86_thiscallcc void @thiscall_cdecl_notail(i32 %a, i32 %b, i32 %c) {
14  tail call void @cdecl_void()
15  ret void
16}
17; CHECK-LABEL: thiscall_cdecl_notail
18; CHECK: calll cdecl_void
19; CHECK: retl $8
20
21define x86_stdcallcc void @stdcall_cdecl_notail(i32 %a, i32 %b, i32 %c) {
22  tail call void @cdecl_void()
23  ret void
24}
25; CHECK-LABEL: stdcall_cdecl_notail
26; CHECK: calll cdecl_void
27; CHECK: retl $12
28
29define x86_vectorcallcc void @vectorcall_cdecl_notail(i32 inreg %a, i32 inreg %b, i32 %c) {
30  tail call void @cdecl_void()
31  ret void
32}
33; CHECK-LABEL: vectorcall_cdecl_notail
34; CHECK: calll cdecl_void
35; CHECK: retl $4
36
37define x86_fastcallcc void @fastcall_cdecl_notail(i32 inreg %a, i32 inreg %b, i32 %c) {
38  tail call void @cdecl_void()
39  ret void
40}
41; CHECK-LABEL: fastcall_cdecl_notail
42; CHECK: calll cdecl_void
43; CHECK: retl $4
44
45
46; Tail call to/from callee pop functions can work under the right circumstances:
47
48declare x86_thiscallcc void @no_args_method(ptr)
49declare x86_thiscallcc void @one_arg_method(ptr, i32)
50declare x86_thiscallcc void @two_args_method(ptr, i32, i32)
51declare void @ccall_func()
52declare void @ccall_func1(i32)
53
54define x86_thiscallcc void @thiscall_thiscall_tail(ptr %this) {
55entry:
56  tail call x86_thiscallcc void @no_args_method(ptr %this)
57  ret void
58}
59; CHECK-LABEL: thiscall_thiscall_tail:
60; CHECK: jmp no_args_method
61
62define x86_thiscallcc void @thiscall_thiscall_tail2(ptr %this, i32 %a, i32 %b) {
63entry:
64  tail call x86_thiscallcc void @two_args_method(ptr %this, i32 %a, i32 %b)
65  ret void
66}
67; @two_args_method will take care of popping %a and %b from the stack for us.
68; CHECK-LABEL: thiscall_thiscall_tail2:
69; CHECK: jmp two_args_method
70
71define x86_thiscallcc void @thiscall_thiscall_notail(ptr %this, i32 %a, i32 %b, i32 %x) {
72entry:
73  tail call x86_thiscallcc void @two_args_method(ptr %this, i32 %a, i32 %b)
74  ret void
75}
76; @two_args_method would not pop %x.
77; CHECK-LABEL: thiscall_thiscall_notail:
78; CHECK: calll two_args_method
79; CHECK: retl $12
80
81define x86_thiscallcc void @thiscall_thiscall_notail2(ptr %this, i32 %a) {
82entry:
83  tail call x86_thiscallcc void @no_args_method(ptr %this)
84  ret void
85}
86; @no_args_method would not pop %x for us. Make sure this is checked even
87; when there are no arguments to the call.
88; CHECK-LABEL: thiscall_thiscall_notail2:
89; CHECK: calll no_args_method
90; CHECK: retl $4
91
92define void @ccall_thiscall_tail(ptr %x) {
93entry:
94  tail call x86_thiscallcc void @no_args_method(ptr %x)
95  ret void
96}
97; Tail calling from ccall to thiscall works.
98; CHECK-LABEL: ccall_thiscall_tail:
99; CHECK: jmp no_args_method
100
101define void @ccall_thiscall_notail(ptr %x, i32 %y) {
102entry:
103  tail call x86_thiscallcc void @one_arg_method(ptr %x, i32 %y);
104  ret void
105}
106; @one_arg_method would pop %y off the stack.
107; CHECK-LABEL: ccall_thiscall_notail:
108; CHECK: calll one_arg_method
109
110define x86_thiscallcc void @thiscall_ccall_tail(ptr %this) {
111entry:
112  tail call void @ccall_func()
113  ret void
114}
115; Tail call from thiscall to ccall works if no arguments need popping.
116; CHECK-LABEL: thiscall_ccall_tail:
117; CHECK: jmp ccall_func
118
119define x86_thiscallcc void @thiscall_ccall_notail(ptr %this, i32 %x) {
120entry:
121  tail call void @ccall_func1(i32 %x)
122  ret void
123}
124; No tail call: %x needs to be popped.
125; CHECK-LABEL: thiscall_ccall_notail:
126; CHECK: calll ccall_func1
127; CHECK: retl $4
128
129%S = type { ptr }
130define x86_thiscallcc void @tailcall_through_pointer(ptr %this, i32 %a) {
131entry:
132  %vtable = load ptr, ptr %this
133  %0 = load ptr, ptr %vtable
134  tail call x86_thiscallcc void %0(ptr %this, i32 %a)
135  ret void
136}
137; Tail calling works through function pointers too.
138; CHECK-LABEL: tailcall_through_pointer:
139; CHECK: jmpl
140
141define x86_stdcallcc void @stdcall_cdecl_tail() {
142  tail call void @ccall_func()
143  ret void
144}
145; stdcall to cdecl works if no arguments need popping.
146; CHECK-LABEL: stdcall_cdecl_tail
147; CHECK: jmp ccall_func
148
149define x86_vectorcallcc void @vectorcall_cdecl_tail(i32 inreg %a, i32 inreg %b) {
150  tail call void @ccall_func()
151  ret void
152}
153; vectorcall to cdecl works if no arguments need popping.
154; CHECK-LABEL: vectorcall_cdecl_tail
155; CHECK: jmp ccall_func
156
157define x86_fastcallcc void @fastcall_cdecl_tail(i32 inreg %a, i32 inreg %b) {
158  tail call void @ccall_func()
159  ret void
160}
161; fastcall to cdecl works if no arguments need popping.
162; CHECK-LABEL: fastcall_cdecl_tail
163; CHECK: jmp ccall_func
164
165define x86_stdcallcc void @stdcall_thiscall_notail(ptr %this, i32 %a, i32 %b) {
166  tail call x86_thiscallcc void @two_args_method(ptr %this, i32 %a, i32 %b)
167  ret void
168}
169; two_args_method will not pop %this.
170; CHECK-LABEL: stdcall_thiscall_notail
171; CHECK: calll two_args_method
172
173define x86_stdcallcc void @stdcall_thiscall_tail(i32 %a, i32 %b) {
174  tail call x86_thiscallcc void @two_args_method(ptr null, i32 %a, i32 %b)
175  ret void
176}
177; The callee pop amounts match up.
178; CHECK-LABEL: stdcall_thiscall_tail
179; CHECK: jmp two_args_method
180
181declare x86_fastcallcc void @fastcall2(i32 inreg %a, i32 inreg %b)
182define void @cdecl_fastcall_tail(i32 %a, i32 %b) {
183  tail call x86_fastcallcc void @fastcall2(i32 inreg %a, i32 inreg %b)
184  ret void
185}
186; fastcall2 won't pop anything.
187; CHECK-LABEL: cdecl_fastcall_tail
188; CHECK: jmp fastcall2
189