llvm.org GIT mirror llvm / dae2873
Verifier: Don't reject varargs callee cleanup functions We've rejected these kinds of functions since r28405 in 2006 because it's impossible to lower the return of a callee cleanup varargs function. However there are lots of legal ways to leave such a function without returning, such as aborting. Today we can leave a function with a musttail call to another function with the correct prototype, and everything works out. I'm removing the verifier check declaring that a normal return from such a function is UB. Reviewed By: nlewycky Differential Revision: http://reviews.llvm.org/D5059 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216779 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 6 years ago
4 changed file(s) with 83 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
10541054 "Attribute 'builtin' can only be applied to a callsite.", &F);
10551055
10561056 // Check that this function meets the restrictions on this calling convention.
1057 // Sometimes varargs is used for perfectly forwarding thunks, so some of these
1058 // restrictions can be lifted.
10571059 switch (F.getCallingConv()) {
10581060 default:
1059 break;
10601061 case CallingConv::C:
10611062 break;
10621063 case CallingConv::Fast:
10631064 case CallingConv::Cold:
1064 case CallingConv::X86_FastCall:
1065 case CallingConv::X86_ThisCall:
10661065 case CallingConv::Intel_OCL_BI:
10671066 case CallingConv::PTX_Kernel:
10681067 case CallingConv::PTX_Device:
1069 Assert1(!F.isVarArg(),
1070 "Varargs functions must have C calling conventions!", &F);
1068 Assert1(!F.isVarArg(), "Calling convention does not support varargs or "
1069 "perfect forwarding!", &F);
10711070 break;
10721071 }
10731072
36043604 /// own arguments. Callee pop is necessary to support tail calls.
36053605 bool X86::isCalleePop(CallingConv::ID CallingConv,
36063606 bool is64Bit, bool IsVarArg, bool TailCallOpt) {
3607 if (IsVarArg)
3608 return false;
3609
36103607 switch (CallingConv) {
36113608 default:
36123609 return false;
36133610 case CallingConv::X86_StdCall:
3614 return !is64Bit;
36153611 case CallingConv::X86_FastCall:
3616 return !is64Bit;
36173612 case CallingConv::X86_ThisCall:
36183613 return !is64Bit;
36193614 case CallingConv::Fast:
3620 return TailCallOpt;
36213615 case CallingConv::GHC:
3622 return TailCallOpt;
36233616 case CallingConv::HiPE:
3617 if (IsVarArg)
3618 return false;
36243619 return TailCallOpt;
36253620 }
36263621 }
0 ; RUN: llc -mtriple=i686-pc-windows < %s | FileCheck %s
1
2 target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
3
4 declare x86_thiscallcc void @thiscall_thunk(i8* %this, ...)
5 define i32 @call_varargs_thiscall_thunk(i8* %a, i32 %b, i32 %c, i32 %d) {
6 call x86_thiscallcc void (i8*, ...)* @thiscall_thunk(i8* %a, i32 1, i32 2)
7 call x86_thiscallcc void (i8*, ...)* @thiscall_thunk(i8* %a, i32 1, i32 2)
8 %t1 = add i32 %b, %c
9 %r = add i32 %t1, %d
10 ret i32 %r
11 }
12
13 ; CHECK: _call_varargs_thiscall_thunk:
14 ; CHECK: calll _thiscall_thunk
15 ; CHECK-NEXT: subl $8, %esp
16
17 ; We don't mangle the argument size into variadic callee cleanup functions.
18
19 declare x86_stdcallcc void @stdcall_thunk(i8* %this, ...)
20 define i32 @call_varargs_stdcall_thunk(i8* %a, i32 %b, i32 %c, i32 %d) {
21 call x86_stdcallcc void (i8*, ...)* @stdcall_thunk(i8* %a, i32 1, i32 2)
22 call x86_stdcallcc void (i8*, ...)* @stdcall_thunk(i8* %a, i32 1, i32 2)
23 %t1 = add i32 %b, %c
24 %r = add i32 %t1, %d
25 ret i32 %r
26 }
27
28 ; CHECK: _call_varargs_stdcall_thunk:
29 ; CHECK: calll _stdcall_thunk{{$}}
30 ; CHECK-NEXT: subl $12, %esp
31
32 declare x86_fastcallcc void @fastcall_thunk(i8* %this, ...)
33 define i32 @call_varargs_fastcall_thunk(i8* %a, i32 %b, i32 %c, i32 %d) {
34 call x86_fastcallcc void (i8*, ...)* @fastcall_thunk(i8* inreg %a, i32 inreg 1, i32 2)
35 call x86_fastcallcc void (i8*, ...)* @fastcall_thunk(i8* inreg %a, i32 inreg 1, i32 2)
36 %t1 = add i32 %b, %c
37 %r = add i32 %t1, %d
38 ret i32 %r
39 }
40
41 ; CHECK: _call_varargs_fastcall_thunk:
42 ; CHECK: calll @fastcall_thunk{{$}}
43 ; CHECK-NEXT: subl $4, %esp
44
45 ; If you actually return from such a thunk, it will only pop the non-variadic
46 ; portion of the arguments, which is different from what the callee passes.
47
48 define x86_stdcallcc void @varargs_stdcall_return(i32, i32, ...) {
49 ret void
50 }
51
52 ; CHECK: _varargs_stdcall_return:
53 ; CHECK: retl $8
1313 %w = bitcast i8* %v to i32*
1414 ret i32* %w
1515 }
16
17 declare x86_thiscallcc void @varargs_thiscall(i8*, ...)
18 define x86_thiscallcc void @varargs_thiscall_thunk(i8* %this, ...) {
19 musttail call x86_thiscallcc void (i8*, ...)* @varargs_thiscall(i8* %this, ...)
20 ret void
21 }
22
23 declare x86_fastcallcc void @varargs_fastcall(i8*, ...)
24 define x86_fastcallcc void @varargs_fastcall_thunk(i8* %this, ...) {
25 musttail call x86_fastcallcc void (i8*, ...)* @varargs_fastcall(i8* %this, ...)
26 ret void
27 }
28
29 define x86_thiscallcc void @varargs_thiscall_unreachable(i8* %this, ...) {
30 unreachable
31 }
32
33 define x86_thiscallcc void @varargs_thiscall_ret_unreachable(i8* %this, ...) {
34 musttail call x86_thiscallcc void (i8*, ...)* @varargs_thiscall(i8* %this, ...)
35 ret void
36 bb1:
37 ret void
38 }