Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / CodeGen / X86 / musttail-indirect.ll
blob092f0cea02d194e1cd1643c14d649b795a52f667
1 ; RUN: llc -verify-machineinstrs < %s -mtriple=i686-win32 | FileCheck %s
2 ; RUN: llc -verify-machineinstrs < %s -mtriple=i686-win32 -O0 | FileCheck %s
4 ; IR simplified from the following C++ snippet compiled for i686-windows-msvc:
6 ; struct A { A(); ~A(); int a; };
8 ; struct B {
9 ;   virtual int  f(int);
10 ;   virtual int  g(A, int, A);
11 ;   virtual void h(A, int, A);
12 ;   virtual A    i(A, int, A);
13 ;   virtual A    j(int);
14 ; };
16 ; int  (B::*mp_f)(int)       = &B::f;
17 ; int  (B::*mp_g)(A, int, A) = &B::g;
18 ; void (B::*mp_h)(A, int, A) = &B::h;
19 ; A    (B::*mp_i)(A, int, A) = &B::i;
20 ; A    (B::*mp_j)(int)       = &B::j;
22 ; Each member pointer creates a thunk.  The ones with inalloca are required to
23 ; tail calls by the ABI, even at O0.
25 %struct.B = type { ptr }
26 %struct.A = type { i32 }
28 ; CHECK-LABEL: f_thunk:
29 ; CHECK: jmpl
30 ; CHECK-NOT: ret
31 define x86_thiscallcc i32 @f_thunk(ptr %this, i32) {
32 entry:
33   %vtable = load ptr, ptr %this
34   %1 = load ptr, ptr %vtable
35   %2 = musttail call x86_thiscallcc i32 %1(ptr %this, i32 %0)
36   ret i32 %2
39 ; Inalloca thunks shouldn't require any stores to the stack.
40 ; CHECK-LABEL: g_thunk:
41 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
42 ; CHECK: jmpl
43 ; CHECK-NOT: ret
44 define x86_thiscallcc i32 @g_thunk(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>)) {
45 entry:
46   %vtable = load ptr, ptr %this
47   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1
48   %1 = load ptr, ptr %vfn
49   %2 = musttail call x86_thiscallcc i32 %1(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>) %0)
50   ret i32 %2
53 ; Preallocated thunks shouldn't require any stores to the stack.
54 ; CHECK-LABEL: g_thunk_preallocated:
55 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
56 ; CHECK: jmpl
57 ; CHECK-NOT: ret
58 define x86_thiscallcc i32 @g_thunk_preallocated(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>)) {
59 entry:
60   %vtable = load ptr, ptr %this
61   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1
62   %1 = load ptr, ptr %vfn
63   %2 = musttail call x86_thiscallcc i32 %1(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>) %0)
64   ret i32 %2
67 ; CHECK-LABEL: h_thunk:
68 ; CHECK: jmpl
69 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
70 ; CHECK-NOT: ret
71 define x86_thiscallcc void @h_thunk(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>)) {
72 entry:
73   %vtable = load ptr, ptr %this
74   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 2
75   %1 = load ptr, ptr %vfn
76   musttail call x86_thiscallcc void %1(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>) %0)
77   ret void
80 ; CHECK-LABEL: h_thunk_preallocated:
81 ; CHECK: jmpl
82 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
83 ; CHECK-NOT: ret
84 define x86_thiscallcc void @h_thunk_preallocated(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>)) {
85 entry:
86   %vtable = load ptr, ptr %this
87   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 2
88   %1 = load ptr, ptr %vfn
89   musttail call x86_thiscallcc void %1(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>) %0)
90   ret void
93 ; CHECK-LABEL: i_thunk:
94 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
95 ; CHECK: jmpl
96 ; CHECK-NOT: ret
97 define x86_thiscallcc ptr @i_thunk(ptr %this, ptr inalloca(<{ ptr, %struct.A, i32, %struct.A }>)) {
98 entry:
99   %vtable = load ptr, ptr %this
100   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 3
101   %1 = load ptr, ptr %vfn
102   %2 = musttail call x86_thiscallcc ptr %1(ptr %this, ptr inalloca(<{ ptr, %struct.A, i32, %struct.A }>) %0)
103   ret ptr %2
106 ; CHECK-LABEL: i_thunk_preallocated:
107 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
108 ; CHECK: jmpl
109 ; CHECK-NOT: ret
110 define x86_thiscallcc ptr @i_thunk_preallocated(ptr %this, ptr preallocated(<{ ptr, %struct.A, i32, %struct.A }>)) {
111 entry:
112   %vtable = load ptr, ptr %this
113   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 3
114   %1 = load ptr, ptr %vfn
115   %2 = musttail call x86_thiscallcc ptr %1(ptr %this, ptr preallocated(<{ ptr, %struct.A, i32, %struct.A }>) %0)
116   ret ptr %2
119 ; CHECK-LABEL: j_thunk:
120 ; CHECK: jmpl
121 ; CHECK-NOT: ret
122 define x86_thiscallcc void @j_thunk(ptr noalias sret(%struct.A) %agg.result, ptr %this, i32) {
123 entry:
124   %vtable = load ptr, ptr %this
125   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 4
126   %1 = load ptr, ptr %vfn
127   musttail call x86_thiscallcc void %1(ptr sret(%struct.A) %agg.result, ptr %this, i32 %0)
128   ret void
131 ; CHECK-LABEL: _stdcall_thunk@8:
132 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
133 ; CHECK: jmpl
134 ; CHECK-NOT: ret
135 define x86_stdcallcc i32 @stdcall_thunk(ptr inalloca(<{ ptr, %struct.A }>)) {
136 entry:
137   %this_ptr = getelementptr inbounds <{ ptr, %struct.A }>, ptr %0, i32 0, i32 0
138   %this = load ptr, ptr %this_ptr
139   %vtable = load ptr, ptr %this
140   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1
141   %1 = load ptr, ptr %vfn
142   %2 = musttail call x86_stdcallcc i32 %1(ptr inalloca(<{ ptr, %struct.A }>) %0)
143   ret i32 %2
146 ; CHECK-LABEL: _stdcall_thunk_preallocated@8:
147 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
148 ; CHECK: jmpl
149 ; CHECK-NOT: ret
150 define x86_stdcallcc i32 @stdcall_thunk_preallocated(ptr preallocated(<{ ptr, %struct.A }>)) {
151 entry:
152   %this_ptr = getelementptr inbounds <{ ptr, %struct.A }>, ptr %0, i32 0, i32 0
153   %this = load ptr, ptr %this_ptr
154   %vtable = load ptr, ptr %this
155   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1
156   %1 = load ptr, ptr %vfn
157   %2 = musttail call x86_stdcallcc i32 %1(ptr preallocated(<{ ptr, %struct.A }>) %0)
158   ret i32 %2
161 ; CHECK-LABEL: @fastcall_thunk@8:
162 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
163 ; CHECK: jmpl
164 ; CHECK-NOT: ret
165 define x86_fastcallcc i32 @fastcall_thunk(ptr inreg %this, ptr inalloca(<{ %struct.A }>)) {
166 entry:
167   %vtable = load ptr, ptr %this
168   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1
169   %1 = load ptr, ptr %vfn
170   %2 = musttail call x86_fastcallcc i32 %1(ptr inreg %this, ptr inalloca(<{ %struct.A }>) %0)
171   ret i32 %2
174 ; CHECK-LABEL: @fastcall_thunk_preallocated@8:
175 ; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}
176 ; CHECK: jmpl
177 ; CHECK-NOT: ret
178 define x86_fastcallcc i32 @fastcall_thunk_preallocated(ptr inreg %this, ptr preallocated(<{ %struct.A }>)) {
179 entry:
180   %vtable = load ptr, ptr %this
181   %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1
182   %1 = load ptr, ptr %vfn
183   %2 = musttail call x86_fastcallcc i32 %1(ptr inreg %this, ptr preallocated(<{ %struct.A }>) %0)
184   ret i32 %2