[llvm] r178291 - Make Win32 put the SRet address into EAX, fixes PR15556

NAKAMURA Takumi geek4civic at gmail.com
Fri Mar 29 11:55:25 PDT 2013


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