brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · dc5a9eb Raw
189 lines · plain
1; RUN: llc -mtriple=i686-unknown-linux-gnu -O1 < %s | FileCheck %s2; RUN: llc -mtriple=i686-unknown-linux-gnu -O0 < %s | FileCheck %s3 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 the11; 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 void16}17; CHECK-LABEL: thiscall_cdecl_notail18; CHECK: calll cdecl_void19; CHECK: retl $820 21define x86_stdcallcc void @stdcall_cdecl_notail(i32 %a, i32 %b, i32 %c) {22  tail call void @cdecl_void()23  ret void24}25; CHECK-LABEL: stdcall_cdecl_notail26; CHECK: calll cdecl_void27; CHECK: retl $1228 29define x86_vectorcallcc void @vectorcall_cdecl_notail(i32 inreg %a, i32 inreg %b, i32 %c) {30  tail call void @cdecl_void()31  ret void32}33; CHECK-LABEL: vectorcall_cdecl_notail34; CHECK: calll cdecl_void35; CHECK: retl $436 37define x86_fastcallcc void @fastcall_cdecl_notail(i32 inreg %a, i32 inreg %b, i32 %c) {38  tail call void @cdecl_void()39  ret void40}41; CHECK-LABEL: fastcall_cdecl_notail42; CHECK: calll cdecl_void43; CHECK: retl $444 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 void58}59; CHECK-LABEL: thiscall_thiscall_tail:60; CHECK: jmp no_args_method61 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 void66}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_method70 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 void75}76; @two_args_method would not pop %x.77; CHECK-LABEL: thiscall_thiscall_notail:78; CHECK: calll two_args_method79; CHECK: retl $1280 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 void85}86; @no_args_method would not pop %x for us. Make sure this is checked even87; when there are no arguments to the call.88; CHECK-LABEL: thiscall_thiscall_notail2:89; CHECK: calll no_args_method90; CHECK: retl $491 92define void @ccall_thiscall_tail(ptr %x) {93entry:94  tail call x86_thiscallcc void @no_args_method(ptr %x)95  ret void96}97; Tail calling from ccall to thiscall works.98; CHECK-LABEL: ccall_thiscall_tail:99; CHECK: jmp no_args_method100 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 void105}106; @one_arg_method would pop %y off the stack.107; CHECK-LABEL: ccall_thiscall_notail:108; CHECK: calll one_arg_method109 110define x86_thiscallcc void @thiscall_ccall_tail(ptr %this) {111entry:112  tail call void @ccall_func()113  ret void114}115; Tail call from thiscall to ccall works if no arguments need popping.116; CHECK-LABEL: thiscall_ccall_tail:117; CHECK: jmp ccall_func118 119define x86_thiscallcc void @thiscall_ccall_notail(ptr %this, i32 %x) {120entry:121  tail call void @ccall_func1(i32 %x)122  ret void123}124; No tail call: %x needs to be popped.125; CHECK-LABEL: thiscall_ccall_notail:126; CHECK: calll ccall_func1127; CHECK: retl $4128 129%S = type { ptr }130define x86_thiscallcc void @tailcall_through_pointer(ptr %this, i32 %a) {131entry:132  %vtable = load ptr, ptr %this133  %0 = load ptr, ptr %vtable134  tail call x86_thiscallcc void %0(ptr %this, i32 %a)135  ret void136}137; Tail calling works through function pointers too.138; CHECK-LABEL: tailcall_through_pointer:139; CHECK: jmpl140 141define x86_stdcallcc void @stdcall_cdecl_tail() {142  tail call void @ccall_func()143  ret void144}145; stdcall to cdecl works if no arguments need popping.146; CHECK-LABEL: stdcall_cdecl_tail147; CHECK: jmp ccall_func148 149define x86_vectorcallcc void @vectorcall_cdecl_tail(i32 inreg %a, i32 inreg %b) {150  tail call void @ccall_func()151  ret void152}153; vectorcall to cdecl works if no arguments need popping.154; CHECK-LABEL: vectorcall_cdecl_tail155; CHECK: jmp ccall_func156 157define x86_fastcallcc void @fastcall_cdecl_tail(i32 inreg %a, i32 inreg %b) {158  tail call void @ccall_func()159  ret void160}161; fastcall to cdecl works if no arguments need popping.162; CHECK-LABEL: fastcall_cdecl_tail163; CHECK: jmp ccall_func164 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 void168}169; two_args_method will not pop %this.170; CHECK-LABEL: stdcall_thiscall_notail171; CHECK: calll two_args_method172 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 void176}177; The callee pop amounts match up.178; CHECK-LABEL: stdcall_thiscall_tail179; CHECK: jmp two_args_method180 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 void185}186; fastcall2 won't pop anything.187; CHECK-LABEL: cdecl_fastcall_tail188; CHECK: jmp fastcall2189