brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 092f0ce Raw
186 lines · plain
1; RUN: llc -verify-machineinstrs < %s -mtriple=i686-win32 | FileCheck %s2; RUN: llc -verify-machineinstrs < %s -mtriple=i686-win32 -O0 | FileCheck %s3 4; IR simplified from the following C++ snippet compiled for i686-windows-msvc:5 6; struct A { A(); ~A(); int a; };7;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; };15;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;21 22; Each member pointer creates a thunk.  The ones with inalloca are required to23; tail calls by the ABI, even at O0.24 25%struct.B = type { ptr }26%struct.A = type { i32 }27 28; CHECK-LABEL: f_thunk:29; CHECK: jmpl30; CHECK-NOT: ret31define x86_thiscallcc i32 @f_thunk(ptr %this, i32) {32entry:33  %vtable = load ptr, ptr %this34  %1 = load ptr, ptr %vtable35  %2 = musttail call x86_thiscallcc i32 %1(ptr %this, i32 %0)36  ret i32 %237}38 39; Inalloca thunks shouldn't require any stores to the stack.40; CHECK-LABEL: g_thunk:41; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}42; CHECK: jmpl43; CHECK-NOT: ret44define x86_thiscallcc i32 @g_thunk(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>)) {45entry:46  %vtable = load ptr, ptr %this47  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 148  %1 = load ptr, ptr %vfn49  %2 = musttail call x86_thiscallcc i32 %1(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>) %0)50  ret i32 %251}52 53; Preallocated thunks shouldn't require any stores to the stack.54; CHECK-LABEL: g_thunk_preallocated:55; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}56; CHECK: jmpl57; CHECK-NOT: ret58define x86_thiscallcc i32 @g_thunk_preallocated(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>)) {59entry:60  %vtable = load ptr, ptr %this61  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 162  %1 = load ptr, ptr %vfn63  %2 = musttail call x86_thiscallcc i32 %1(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>) %0)64  ret i32 %265}66 67; CHECK-LABEL: h_thunk:68; CHECK: jmpl69; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}70; CHECK-NOT: ret71define x86_thiscallcc void @h_thunk(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>)) {72entry:73  %vtable = load ptr, ptr %this74  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 275  %1 = load ptr, ptr %vfn76  musttail call x86_thiscallcc void %1(ptr %this, ptr inalloca(<{ %struct.A, i32, %struct.A }>) %0)77  ret void78}79 80; CHECK-LABEL: h_thunk_preallocated:81; CHECK: jmpl82; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}83; CHECK-NOT: ret84define x86_thiscallcc void @h_thunk_preallocated(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>)) {85entry:86  %vtable = load ptr, ptr %this87  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 288  %1 = load ptr, ptr %vfn89  musttail call x86_thiscallcc void %1(ptr %this, ptr preallocated(<{ %struct.A, i32, %struct.A }>) %0)90  ret void91}92 93; CHECK-LABEL: i_thunk:94; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}95; CHECK: jmpl96; CHECK-NOT: ret97define x86_thiscallcc ptr @i_thunk(ptr %this, ptr inalloca(<{ ptr, %struct.A, i32, %struct.A }>)) {98entry:99  %vtable = load ptr, ptr %this100  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 3101  %1 = load ptr, ptr %vfn102  %2 = musttail call x86_thiscallcc ptr %1(ptr %this, ptr inalloca(<{ ptr, %struct.A, i32, %struct.A }>) %0)103  ret ptr %2104}105 106; CHECK-LABEL: i_thunk_preallocated:107; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}108; CHECK: jmpl109; CHECK-NOT: ret110define x86_thiscallcc ptr @i_thunk_preallocated(ptr %this, ptr preallocated(<{ ptr, %struct.A, i32, %struct.A }>)) {111entry:112  %vtable = load ptr, ptr %this113  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 3114  %1 = load ptr, ptr %vfn115  %2 = musttail call x86_thiscallcc ptr %1(ptr %this, ptr preallocated(<{ ptr, %struct.A, i32, %struct.A }>) %0)116  ret ptr %2117}118 119; CHECK-LABEL: j_thunk:120; CHECK: jmpl121; CHECK-NOT: ret122define x86_thiscallcc void @j_thunk(ptr noalias sret(%struct.A) %agg.result, ptr %this, i32) {123entry:124  %vtable = load ptr, ptr %this125  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 4126  %1 = load ptr, ptr %vfn127  musttail call x86_thiscallcc void %1(ptr sret(%struct.A) %agg.result, ptr %this, i32 %0)128  ret void129}130 131; CHECK-LABEL: _stdcall_thunk@8:132; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}133; CHECK: jmpl134; CHECK-NOT: ret135define x86_stdcallcc i32 @stdcall_thunk(ptr inalloca(<{ ptr, %struct.A }>)) {136entry:137  %this_ptr = getelementptr inbounds <{ ptr, %struct.A }>, ptr %0, i32 0, i32 0138  %this = load ptr, ptr %this_ptr139  %vtable = load ptr, ptr %this140  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1141  %1 = load ptr, ptr %vfn142  %2 = musttail call x86_stdcallcc i32 %1(ptr inalloca(<{ ptr, %struct.A }>) %0)143  ret i32 %2144}145 146; CHECK-LABEL: _stdcall_thunk_preallocated@8:147; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}148; CHECK: jmpl149; CHECK-NOT: ret150define x86_stdcallcc i32 @stdcall_thunk_preallocated(ptr preallocated(<{ ptr, %struct.A }>)) {151entry:152  %this_ptr = getelementptr inbounds <{ ptr, %struct.A }>, ptr %0, i32 0, i32 0153  %this = load ptr, ptr %this_ptr154  %vtable = load ptr, ptr %this155  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1156  %1 = load ptr, ptr %vfn157  %2 = musttail call x86_stdcallcc i32 %1(ptr preallocated(<{ ptr, %struct.A }>) %0)158  ret i32 %2159}160 161; CHECK-LABEL: @fastcall_thunk@8:162; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}163; CHECK: jmpl164; CHECK-NOT: ret165define x86_fastcallcc i32 @fastcall_thunk(ptr inreg %this, ptr inalloca(<{ %struct.A }>)) {166entry:167  %vtable = load ptr, ptr %this168  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1169  %1 = load ptr, ptr %vfn170  %2 = musttail call x86_fastcallcc i32 %1(ptr inreg %this, ptr inalloca(<{ %struct.A }>) %0)171  ret i32 %2172}173 174; CHECK-LABEL: @fastcall_thunk_preallocated@8:175; CHECK-NOT: mov %{{.*}}, {{.*(.*esp.*)}}176; CHECK: jmpl177; CHECK-NOT: ret178define x86_fastcallcc i32 @fastcall_thunk_preallocated(ptr inreg %this, ptr preallocated(<{ %struct.A }>)) {179entry:180  %vtable = load ptr, ptr %this181  %vfn = getelementptr inbounds ptr, ptr %vtable, i32 1182  %1 = load ptr, ptr %vfn183  %2 = musttail call x86_fastcallcc i32 %1(ptr inreg %this, ptr preallocated(<{ %struct.A }>) %0)184  ret i32 %2185}186