llvm.org GIT mirror llvm / 9a2478a
Support MSVC x86-32 sret convention. PR11688. Patch by Joe Groff. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148513 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Friedman 8 years ago
3 changed file(s) with 37 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
18541854 // Issue CALLSEQ_END
18551855 unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
18561856 unsigned NumBytesCallee = 0;
1857 if (!Subtarget->is64Bit() && CS.paramHasAttr(1, Attribute::StructRet))
1857 if (!Subtarget->is64Bit() && !Subtarget->isTargetWindows() &&
1858 CS.paramHasAttr(1, Attribute::StructRet))
18581859 NumBytesCallee = 4;
18591860 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(AdjStackUp))
18601861 .addImm(NumBytes).addImm(NumBytesCallee);
18101810
18111811 MachineFrameInfo *MFI = MF.getFrameInfo();
18121812 bool Is64Bit = Subtarget->is64Bit();
1813 bool IsWindows = Subtarget->isTargetWindows();
18131814 bool IsWin64 = Subtarget->isTargetWin64();
18141815
18151816 assert(!(isVarArg && IsTailCallConvention(CallConv)) &&
20452046 } else {
20462047 FuncInfo->setBytesToPopOnReturn(0); // Callee pops nothing.
20472048 // If this is an sret function, the return should pop the hidden pointer.
2048 if (!Is64Bit && !IsTailCallConvention(CallConv) && ArgsAreStructReturn(Ins))
2049 if (!Is64Bit && !IsTailCallConvention(CallConv) && !IsWindows &&
2050 ArgsAreStructReturn(Ins))
20492051 FuncInfo->setBytesToPopOnReturn(4);
20502052 }
20512053
21292131 MachineFunction &MF = DAG.getMachineFunction();
21302132 bool Is64Bit = Subtarget->is64Bit();
21312133 bool IsWin64 = Subtarget->isTargetWin64();
2134 bool IsWindows = Subtarget->isTargetWindows();
21322135 bool IsStructRet = CallIsStructReturn(Outs);
21332136 bool IsSibcall = false;
21342137
25422545 if (X86::isCalleePop(CallConv, Is64Bit, isVarArg,
25432546 getTargetMachine().Options.GuaranteedTailCallOpt))
25442547 NumBytesForCalleeToPush = NumBytes; // Callee pops everything
2545 else if (!Is64Bit && !IsTailCallConvention(CallConv) && IsStructRet)
2548 else if (!Is64Bit && !IsTailCallConvention(CallConv) && !IsWindows &&
2549 IsStructRet)
25462550 // If this is a call to a struct-return function, the callee
25472551 // pops the hidden struct pointer, so we have to push it back.
25482552 // This is common for Darwin/X86, Linux & Mingw32 targets.
2553 // For MSVC Win32 targets, the caller pops the hidden struct pointer.
25492554 NumBytesForCalleeToPush = 4;
25502555 else
25512556 NumBytesForCalleeToPush = 0; // Callee pops nothing.
0 ; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32
1 ; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32
2 ; RUN: llc < %s -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
3 ; RUN: llc < %s -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32
4 ; RUN: llc < %s -O0 -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32
5 ; RUN: llc < %s -O0 -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
6
7 ; The SysV ABI used by most Unixes and Mingw on x86 specifies that an sret pointer
8 ; is callee-cleanup. However, in MSVC's cdecl calling convention, sret pointer
9 ; arguments are caller-cleanup like normal arguments.
10
11 define void @sret1(i8* sret) nounwind {
12 entry:
13 ; WIN_X32: {{ret$}}
14 ; MINGW_X32: ret $4
15 ; LINUX: ret $4
16 ret void
17 }
18
19 define void @sret2(i32* sret %x, i32 %y) nounwind {
20 entry:
21 ; WIN_X32: {{ret$}}
22 ; MINGW_X32: ret $4
23 ; LINUX: ret $4
24 store i32 %y, i32* %x
25 ret void
26 }
27