diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 7f0718b2708..fa19e7d0635 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -2107,14 +2107,15 @@ X86TargetLowering::LowerReturn(SDValue Chain, // 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 (DAG.getMachineFunction().getFunction()->hasStructRetAttr() && - (Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC())) { - MachineFunction &MF = DAG.getMachineFunction(); - X86MachineFunctionInfo *FuncInfo = MF.getInfo(); - unsigned Reg = FuncInfo->getSRetReturnReg(); - assert(Reg && - "SRetReturnReg should have been set in LowerFormalArguments()."); - SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy()); + // + // Checking Function.hasStructRetAttr() here is insufficient because the IR + // may not have an explicit sret argument. If FuncInfo.CanLowerReturn is + // false, then an sret argument may be implicitly inserted in the SelDAG. In + // either case FuncInfo->setSRetReturnReg() will have been called. + if (unsigned SRetReg = FuncInfo->getSRetReturnReg()) { + assert((Subtarget->is64Bit() || Subtarget->isTargetKnownWindowsMSVC()) && + "No need for an sret register"); + SDValue Val = DAG.getCopyFromReg(Chain, dl, SRetReg, getPointerTy()); unsigned RetValReg = (Subtarget->is64Bit() && !Subtarget->isTarget64BitILP32()) ? diff --git a/test/CodeGen/X86/sret-implicit.ll b/test/CodeGen/X86/sret-implicit.ll new file mode 100644 index 00000000000..3fade1de0cf --- /dev/null +++ b/test/CodeGen/X86/sret-implicit.ll @@ -0,0 +1,10 @@ +; RUN: llc -mtriple=x86_64-apple-darwin8 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-pc-linux < %s | FileCheck %s + +; CHECK-LABEL: return32 +; CHECK-DAG: movq $0, (%rdi) +; CHECK-DAG: movq %rdi, %rax +; CHECK: retq +define i256 @return32() { + ret i256 0 +} diff --git a/test/CodeGen/X86/vselect.ll b/test/CodeGen/X86/vselect.ll index c1e9329859c..2e3d7f5428f 100644 --- a/test/CodeGen/X86/vselect.ll +++ b/test/CodeGen/X86/vselect.ll @@ -275,6 +275,7 @@ define <16 x double> @select_illegal(<16 x double> %a, <16 x double> %b) { ; CHECK-NEXT: movaps %xmm2, 32(%rdi) ; CHECK-NEXT: movaps %xmm1, 16(%rdi) ; CHECK-NEXT: movaps %xmm0, (%rdi) +; CHECK-NEXT: movq %rdi, %rax ; CHECK-NEXT: retq %sel = select <16 x i1> , <16 x double> %a, <16 x double> %b ret <16 x double> %sel