diff options
author | Andrew Trick <atrick@apple.com> | 2015-02-05 18:09:05 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2015-02-05 18:09:05 +0000 |
commit | 7fc4583eda562daf9d3610d6e2623c60ca0690f6 (patch) | |
tree | b40f3cb0a6c321722f4a7e9476e656603d1e349d /llvm/lib/Target/X86/X86ISelLowering.cpp | |
parent | f297dbed487cd02514ee3e022c89dc2242475465 (diff) | |
download | bcm5719-llvm-7fc4583eda562daf9d3610d6e2623c60ca0690f6.tar.gz bcm5719-llvm-7fc4583eda562daf9d3610d6e2623c60ca0690f6.zip |
X86 ABI fix for return values > 24 bytes.
The return value's address must be returned in %rax.
i.e. the callee needs to copy the sret argument (%rdi)
into the return value (%rax).
This probably won't manifest as a bug when the caller is LLVM-compiled
code. But it is an ABI guarantee and tools expect it.
llvm-svn: 228321
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 7f0718b2708..fa19e7d0635 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/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<X86MachineFunctionInfo>(); - 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()) ? |