diff options
-rw-r--r-- | llvm/lib/CodeGen/CallingConvLower.cpp | 19 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/musttail-varargs.ll | 14 |
2 files changed, 30 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp index fbe8b7c10e6..034ffb34b9c 100644 --- a/llvm/lib/CodeGen/CallingConvLower.cpp +++ b/llvm/lib/CodeGen/CallingConvLower.cpp @@ -181,15 +181,28 @@ void CCState::AnalyzeCallResult(MVT VT, CCAssignFn Fn) { } } +static bool isValueTypeInRegForCC(CallingConv::ID CC, MVT VT) { + if (VT.isVector()) + return true; // Assume -msse-regparm might be in effect. + if (!VT.isInteger()) + return false; + if (CC == CallingConv::X86_VectorCall || CC == CallingConv::X86_FastCall) + return true; + return false; +} + void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs, MVT VT, CCAssignFn Fn) { unsigned SavedStackOffset = StackOffset; unsigned NumLocs = Locs.size(); - // Allocate something of this value type repeatedly with just the inreg flag - // set until we get assigned a location in memory. + // Set the 'inreg' flag if it is used for this calling convention. ISD::ArgFlagsTy Flags; - Flags.setInReg(); + if (isValueTypeInRegForCC(CallingConv, VT)) + Flags.setInReg(); + + // Allocate something of this value type repeatedly until we get assigned a + // location in memory. bool HaveRegParm = true; while (HaveRegParm) { if (Fn(0, VT, VT, CCValAssign::Full, Flags, *this)) { diff --git a/llvm/test/CodeGen/X86/musttail-varargs.ll b/llvm/test/CodeGen/X86/musttail-varargs.ll index b6ca184e71f..7f105a13a6a 100644 --- a/llvm/test/CodeGen/X86/musttail-varargs.ll +++ b/llvm/test/CodeGen/X86/musttail-varargs.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-linux | FileCheck %s --check-prefix=LINUX ; RUN: llc < %s -enable-tail-merge=0 -mtriple=x86_64-windows | FileCheck %s --check-prefix=WINDOWS +; RUN: llc < %s -enable-tail-merge=0 -mtriple=i686-windows | FileCheck %s --check-prefix=X86 ; Test that we actually spill and reload all arguments in the variadic argument ; pack. Doing a normal call will clobber all argument registers, and we will @@ -72,6 +73,12 @@ define void @f_thunk(i8* %this, ...) { ; WINDOWS-NOT: mov{{.}}ps ; WINDOWS: jmpq *{{.*}} # TAILCALL +; No regparms on normal x86 conventions. + +; X86-LABEL: _f_thunk: +; X86: calll _get_f +; X86: jmpl *{{.*}} # TAILCALL + ; This thunk shouldn't require any spills and reloads, assuming the register ; allocator knows what it's doing. @@ -89,6 +96,9 @@ define void @g_thunk(i8* %fptr_i8, ...) { ; WINDOWS-NOT: movq ; WINDOWS: jmpq *%rcx # TAILCALL +; X86-LABEL: _g_thunk: +; X86: jmpl *%eax # TAILCALL + ; Do a simple multi-exit multi-bb test. %struct.Foo = type { i1, i8*, i8* } @@ -124,3 +134,7 @@ else: ; WINDOWS: jne ; WINDOWS: jmpq *{{.*}} # TAILCALL ; WINDOWS: jmpq *{{.*}} # TAILCALL +; X86-LABEL: _h_thunk: +; X86: jne +; X86: jmpl *{{.*}} # TAILCALL +; X86: jmpl *{{.*}} # TAILCALL |