Re-land r237175: [X86] Always return the sret parameter in eax/rax ...

This reverts commit r237210.

Also fix X86/complex-fca.ll to match the code that we used to generate
on win32 and now generate everwhere to conform to SysV.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237639 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Kleckner 2015-05-18 23:35:09 +00:00
parent 42d8237570
commit 37f1bba13a
4 changed files with 70 additions and 50 deletions

View File

@ -2000,9 +2000,8 @@ X86TargetLowering::LowerReturn(SDValue Chain,
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
} }
// The x86-64 ABIs require that for returning structs by value we copy // All x86 ABIs require that for returning structs by value we copy
// the sret argument into %rax/%eax (depending on ABI) for the return. // 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, // We saved the argument into a virtual register in the entry block,
// so now we copy the value out and into %rax/%eax. // so now we copy the value out and into %rax/%eax.
// //
@ -2011,8 +2010,6 @@ X86TargetLowering::LowerReturn(SDValue Chain,
// false, then an sret argument may be implicitly inserted in the SelDAG. In // false, then an sret argument may be implicitly inserted in the SelDAG. In
// either case FuncInfo->setSRetReturnReg() will have been called. // either case FuncInfo->setSRetReturnReg() will have been called.
if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) { if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) {
assert((Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC()) &&
"No need for an sret register");
SDValue Val = DAG.getCopyFromReg(Chain, dl, SRetReg, getPointerTy()); SDValue Val = DAG.getCopyFromReg(Chain, dl, SRetReg, getPointerTy());
unsigned RetValReg unsigned RetValReg
@ -2442,13 +2439,11 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
InVals.push_back(ArgValue); InVals.push_back(ArgValue);
} }
if (Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC()) {
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
// The x86-64 ABIs require that for returning structs by value we copy // All x86 ABIs require that for returning structs by value we copy the
// the sret argument into %rax/%eax (depending on ABI) for the return. // sret argument into %rax/%eax (depending on ABI) for the return. Save
// Win32 requires us to put the sret argument to %eax as well. // the argument into a virtual register so that we can access it from the
// Save the argument into a virtual register so that we can access it // return points.
// from the return points.
if (Ins[i].Flags.isSRet()) { if (Ins[i].Flags.isSRet()) {
unsigned Reg = FuncInfo->getSRetReturnReg(); unsigned Reg = FuncInfo->getSRetReturnReg();
if (!Reg) { if (!Reg) {
@ -2461,7 +2456,6 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
break; break;
} }
} }
}
unsigned StackSize = CCInfo.getNextStackOffset(); unsigned StackSize = CCInfo.getNextStackOffset();
// Align stack specially for tail calls. // Align stack specially for tail calls.

View File

@ -143,19 +143,19 @@ entry:
; NOCMOV-NEXT: jp [[TBB]] ; NOCMOV-NEXT: jp [[TBB]]
; NOCMOV-NEXT: leal 24(%esp), %eax ; NOCMOV-NEXT: leal 24(%esp), %eax
; NOCMOV-NEXT: [[TBB]]: ; NOCMOV-NEXT: [[TBB]]:
; NOCMOV-NEXT: movl (%eax), %eax ; NOCMOV-NEXT: movl (%eax), %ecx
; NOCMOV-NEXT: leal 44(%esp), %ecx ; NOCMOV-NEXT: leal 44(%esp), %edx
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]] ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
; NOCMOV-NEXT: jp [[TBB]] ; NOCMOV-NEXT: jp [[TBB]]
; NOCMOV-NEXT: leal 28(%esp), %ecx ; NOCMOV-NEXT: leal 28(%esp), %edx
; NOCMOV-NEXT: [[TBB]]: ; NOCMOV-NEXT: [[TBB]]:
; NOCMOV-NEXT: movl (%ecx), %ecx ; NOCMOV-NEXT: movl 12(%esp), %eax
; NOCMOV-NEXT: movl (%edx), %edx
; NOCMOV-NEXT: leal 48(%esp), %esi ; NOCMOV-NEXT: leal 48(%esp), %esi
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]] ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
; NOCMOV-NEXT: jp [[TBB]] ; NOCMOV-NEXT: jp [[TBB]]
; NOCMOV-NEXT: leal 32(%esp), %esi ; NOCMOV-NEXT: leal 32(%esp), %esi
; NOCMOV-NEXT: [[TBB]]: ; NOCMOV-NEXT: [[TBB]]:
; NOCMOV-NEXT: movl 12(%esp), %edx
; NOCMOV-NEXT: movl (%esi), %esi ; NOCMOV-NEXT: movl (%esi), %esi
; NOCMOV-NEXT: leal 52(%esp), %edi ; NOCMOV-NEXT: leal 52(%esp), %edi
; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]] ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
@ -163,10 +163,10 @@ entry:
; NOCMOV-NEXT: leal 36(%esp), %edi ; NOCMOV-NEXT: leal 36(%esp), %edi
; NOCMOV-NEXT: [[TBB]]: ; NOCMOV-NEXT: [[TBB]]:
; NOCMOV-NEXT: movl (%edi), %edi ; NOCMOV-NEXT: movl (%edi), %edi
; NOCMOV-NEXT: movl %edi, 12(%edx) ; NOCMOV-NEXT: movl %edi, 12(%eax)
; NOCMOV-NEXT: movl %esi, 8(%edx) ; NOCMOV-NEXT: movl %esi, 8(%eax)
; NOCMOV-NEXT: movl %ecx, 4(%edx) ; NOCMOV-NEXT: movl %edx, 4(%eax)
; NOCMOV-NEXT: movl %eax, (%edx) ; NOCMOV-NEXT: movl %ecx, (%eax)
; NOCMOV-NEXT: popl %esi ; NOCMOV-NEXT: popl %esi
; NOCMOV-NEXT: popl %edi ; NOCMOV-NEXT: popl %edi
; NOCMOV-NEXT: retl $4 ; NOCMOV-NEXT: retl $4

View File

@ -1,7 +1,4 @@
; RUN: llc < %s -march=x86 | grep mov | count 2 ; RUN: llc < %s -march=x86 | FileCheck %s
; Skip this on Windows as there is no ccosl and sret behaves differently.
; XFAIL: pc-win32
define void @ccosl({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 } %z) nounwind { define void @ccosl({ x86_fp80, x86_fp80 }* noalias sret %agg.result, { x86_fp80, x86_fp80 } %z) nounwind {
entry: entry:
@ -14,4 +11,11 @@ entry:
ret void ret void
} }
; CHECK-LABEL: ccosl:
; CHECK: movl {{[0-9]+}}(%esp), %[[sret_reg:[^ ]+]]
; CHECK: movl %[[sret_reg]], (%esp)
; CHECK: calll {{.*ccoshl.*}}
; CHECK: movl %[[sret_reg]], %eax
; CHECK: retl
declare void @ccoshl({ x86_fp80, x86_fp80 }* noalias sret, { x86_fp80, x86_fp80 }) nounwind declare void @ccoshl({ x86_fp80, x86_fp80 }* noalias sret, { x86_fp80, x86_fp80 }) nounwind

View File

@ -1,12 +1,34 @@
; RUN: llc -mtriple=x86_64-apple-darwin8 < %s | FileCheck %s ; RUN: llc -mtriple=x86_64-apple-darwin8 < %s | FileCheck %s --check-prefix=X64
; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s ; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s --check-prefix=X64
; RUN: llc -mtriple=x86_64-apple-darwin8 -terminal-rule < %s | FileCheck %s ; RUN: llc -mtriple=i686-pc-linux < %s | FileCheck %s --check-prefix=X86
; RUN: llc -mtriple=x86_64-pc-linux -terminal-rule < %s | FileCheck %s ; RUN: llc -mtriple=x86_64-apple-darwin8 -terminal-rule < %s | FileCheck %s --check-prefix=X64
; RUN: llc -mtriple=x86_64-pc-linux -terminal-rule < %s | FileCheck %s --check-prefix=X64
; CHECK-LABEL: return32 define void @sret_void(i32* sret %p) {
; CHECK-DAG: movq $0, (%rdi) store i32 0, i32* %p
; CHECK-DAG: movq %rdi, %rax ret void
; CHECK: retq }
define i256 @return32() {
; X64-LABEL: sret_void
; X64-DAG: movl $0, (%rdi)
; X64-DAG: movq %rdi, %rax
; X64: retq
; X86-LABEL: sret_void
; X86: movl 4(%esp), %eax
; X86: movl $0, (%eax)
; X86: retl
define i256 @sret_demoted() {
ret i256 0 ret i256 0
} }
; X64-LABEL: sret_demoted
; X64-DAG: movq $0, (%rdi)
; X64-DAG: movq %rdi, %rax
; X64: retq
; X86-LABEL: sret_demoted
; X86: movl 4(%esp), %eax
; X86: movl $0, (%eax)
; X86: retl