[llvm] r178291 - Make Win32 put the SRet address into EAX, fixes PR15556
Timur Iskhodzhanov
timurrrr at google.com
Fri Mar 29 14:55:22 PDT 2013
Should be fixed by r178375.
Thanks for noticing!
2013/3/29 Timur Iskhodzhanov <timurrrr at google.com>:
> Which one, X86___complex-fca.ll ?
>
> 2013/3/29 NAKAMURA Takumi <geek4civic at gmail.com>:
>> Timur, I guess you should update one more test as well.
>> See also; http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/246
>>
>> ...Takumi
>>
>> 2013/3/29 Timur Iskhodzhanov <timurrrr at google.com>:
>>> Author: timurrrr
>>> Date: Thu Mar 28 16:30:04 2013
>>> New Revision: 178291
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=178291&view=rev
>>> Log:
>>> Make Win32 put the SRet address into EAX, fixes PR15556
>>>
>>> Modified:
>>> llvm/trunk/lib/Target/X86/X86FastISel.cpp
>>> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>> llvm/trunk/test/CodeGen/X86/win32_sret.ll
>>>
>>> Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=178291&r1=178290&r2=178291&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
>>> +++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Thu Mar 28 16:30:04 2013
>>> @@ -816,14 +816,16 @@ bool X86FastISel::X86SelectRet(const Ins
>>> // The x86-64 ABI for returning structs by value requires that we copy
>>> // the sret argument into %rax for the return. We saved the argument into
>>> // a virtual register in the entry block, so now we copy the value out
>>> - // and into %rax.
>>> - if (Subtarget->is64Bit() && F.hasStructRetAttr()) {
>>> + // and into %rax. We also do the same with %eax for Win32.
>>> + if (F.hasStructRetAttr() &&
>>> + (Subtarget->is64Bit() || Subtarget->isTargetWindows())) {
>>> unsigned Reg = X86MFInfo->getSRetReturnReg();
>>> assert(Reg &&
>>> "SRetReturnReg should have been set in LowerFormalArguments()!");
>>> + unsigned RetReg = Subtarget->is64Bit() ? X86::RAX : X86::EAX;
>>> BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
>>> - X86::RAX).addReg(Reg);
>>> - RetRegs.push_back(X86::RAX);
>>> + RetReg).addReg(Reg);
>>> + RetRegs.push_back(RetReg);
>>> }
>>>
>>> // Now emit the RET.
>>>
>>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=178291&r1=178290&r2=178291&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Mar 28 16:30:04 2013
>>> @@ -1666,10 +1666,11 @@ X86TargetLowering::LowerReturn(SDValue C
>>>
>>> // The x86-64 ABIs require that for returning structs by value we copy
>>> // the sret argument into %rax/%eax (depending on ABI) for the return.
>>> + // Win32 requires us to put the sret argument to %eax as well.
>>> // We saved the argument into a virtual register in the entry block,
>>> // so now we copy the value out and into %rax/%eax.
>>> - if (Subtarget->is64Bit() &&
>>> - DAG.getMachineFunction().getFunction()->hasStructRetAttr()) {
>>> + if (DAG.getMachineFunction().getFunction()->hasStructRetAttr() &&
>>> + (Subtarget->is64Bit() || Subtarget->isTargetWindows())) {
>>> MachineFunction &MF = DAG.getMachineFunction();
>>> X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
>>> unsigned Reg = FuncInfo->getSRetReturnReg();
>>> @@ -1677,12 +1678,14 @@ X86TargetLowering::LowerReturn(SDValue C
>>> "SRetReturnReg should have been set in LowerFormalArguments().");
>>> SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy());
>>>
>>> - unsigned RetValReg = Subtarget->isTarget64BitILP32() ? X86::EAX : X86::RAX;
>>> + unsigned RetValReg
>>> + = (Subtarget->is64Bit() && !Subtarget->isTarget64BitILP32()) ?
>>> + X86::RAX : X86::EAX;
>>> Chain = DAG.getCopyToReg(Chain, dl, RetValReg, Val, Flag);
>>> Flag = Chain.getValue(1);
>>>
>>> // RAX/EAX now acts like a return value.
>>> - RetOps.push_back(DAG.getRegister(RetValReg, MVT::i64));
>>> + RetOps.push_back(DAG.getRegister(RetValReg, getPointerTy()));
>>> }
>>>
>>> RetOps[0] = Chain; // Update chain.
>>> @@ -2036,9 +2039,11 @@ X86TargetLowering::LowerFormalArguments(
>>>
>>> // The x86-64 ABIs require that for returning structs by value we copy
>>> // the sret argument into %rax/%eax (depending on ABI) for the return.
>>> + // Win32 requires us to put the sret argument to %eax as well.
>>> // Save the argument into a virtual register so that we can access it
>>> // from the return points.
>>> - if (Is64Bit && MF.getFunction()->hasStructRetAttr()) {
>>> + if (MF.getFunction()->hasStructRetAttr() &&
>>> + (Subtarget->is64Bit() || Subtarget->isTargetWindows())) {
>>> X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
>>> unsigned Reg = FuncInfo->getSRetReturnReg();
>>> if (!Reg) {
>>>
>>> Modified: llvm/trunk/test/CodeGen/X86/win32_sret.ll
>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win32_sret.ll?rev=178291&r1=178290&r2=178291&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/test/CodeGen/X86/win32_sret.ll (original)
>>> +++ llvm/trunk/test/CodeGen/X86/win32_sret.ll Thu Mar 28 16:30:04 2013
>>> @@ -1,28 +1,84 @@
>>> -; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32
>>> -; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32
>>> +; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN32
>>> +; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X86
>>> ; RUN: llc < %s -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
>>> -; RUN: llc < %s -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32
>>> -; RUN: llc < %s -O0 -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32
>>> +; RUN: llc < %s -O0 -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN32
>>> +; RUN: llc < %s -O0 -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X86
>>> ; RUN: llc < %s -O0 -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
>>>
>>> ; The SysV ABI used by most Unixes and Mingw on x86 specifies that an sret pointer
>>> ; is callee-cleanup. However, in MSVC's cdecl calling convention, sret pointer
>>> ; arguments are caller-cleanup like normal arguments.
>>>
>>> -define void @sret1(i8* sret) nounwind {
>>> +define void @sret1(i8* sret %x) nounwind {
>>> entry:
>>> -; WIN_X32: {{ret$}}
>>> -; MINGW_X32: ret $4
>>> +; WIN32: sret1
>>> +; WIN32: movb $42, (%eax)
>>> +; WIN32-NOT: popl %eax
>>> +; WIN32: {{ret$}}
>>> +
>>> +; MINGW_X86: sret1
>>> +; MINGW_X86: ret $4
>>> +
>>> +; LINUX: sret1
>>> ; LINUX: ret $4
>>> +
>>> + store i8 42, i8* %x, align 4
>>> ret void
>>> }
>>>
>>> -define void @sret2(i32* sret %x, i32 %y) nounwind {
>>> +define void @sret2(i8* sret %x, i8 %y) nounwind {
>>> entry:
>>> -; WIN_X32: {{ret$}}
>>> -; MINGW_X32: ret $4
>>> +; WIN32: sret2
>>> +; WIN32: movb {{.*}}, (%eax)
>>> +; WIN32-NOT: popl %eax
>>> +; WIN32: {{ret$}}
>>> +
>>> +; MINGW_X86: sret2
>>> +; MINGW_X86: ret $4
>>> +
>>> +; LINUX: sret2
>>> ; LINUX: ret $4
>>> - store i32 %y, i32* %x
>>> +
>>> + store i8 %y, i8* %x
>>> ret void
>>> }
>>>
>>> +define void @sret3(i8* sret %x, i8* %y) nounwind {
>>> +entry:
>>> +; WIN32: sret3
>>> +; WIN32: movb $42, (%eax)
>>> +; WIN32-NOT: movb $13, (%eax)
>>> +; WIN32-NOT: popl %eax
>>> +; WIN32: {{ret$}}
>>> +
>>> +; MINGW_X86: sret3
>>> +; MINGW_X86: ret $4
>>> +
>>> +; LINUX: sret3
>>> +; LINUX: ret $4
>>> +
>>> + store i8 42, i8* %x
>>> + store i8 13, i8* %y
>>> + ret void
>>> +}
>>> +
>>> +; PR15556
>>> +%struct.S4 = type { i32, i32, i32 }
>>> +
>>> +define void @sret4(%struct.S4* noalias sret %agg.result) {
>>> +entry:
>>> +; WIN32: sret4
>>> +; WIN32: movl $42, (%eax)
>>> +; WIN32-NOT: popl %eax
>>> +; WIN32: {{ret$}}
>>> +
>>> +; MINGW_X86: sret4
>>> +; MINGW_X86: ret $4
>>> +
>>> +; LINUX: sret4
>>> +; LINUX: ret $4
>>> +
>>> + %x = getelementptr inbounds %struct.S4* %agg.result, i32 0, i32 0
>>> + store i32 42, i32* %x, align 4
>>> + ret void
>>> +}
>>>
>>>
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list