mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Make sure to put our sret argument into %rax on x86-64. Fixes PR13563!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165063 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6c0c6d613a
commit
b09649b335
@ -710,6 +710,8 @@ bool X86FastISel::X86SelectStore(const Instruction *I) {
|
|||||||
bool X86FastISel::X86SelectRet(const Instruction *I) {
|
bool X86FastISel::X86SelectRet(const Instruction *I) {
|
||||||
const ReturnInst *Ret = cast<ReturnInst>(I);
|
const ReturnInst *Ret = cast<ReturnInst>(I);
|
||||||
const Function &F = *I->getParent()->getParent();
|
const Function &F = *I->getParent()->getParent();
|
||||||
|
const X86MachineFunctionInfo *X86MFInfo =
|
||||||
|
FuncInfo.MF->getInfo<X86MachineFunctionInfo>();
|
||||||
|
|
||||||
if (!FuncInfo.CanLowerReturn)
|
if (!FuncInfo.CanLowerReturn)
|
||||||
return false;
|
return false;
|
||||||
@ -724,8 +726,7 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Don't handle popping bytes on return for now.
|
// Don't handle popping bytes on return for now.
|
||||||
if (FuncInfo.MF->getInfo<X86MachineFunctionInfo>()
|
if (X86MFInfo->getBytesToPopOnReturn() != 0)
|
||||||
->getBytesToPopOnReturn() != 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// fastcc with -tailcallopt is intended to provide a guaranteed
|
// fastcc with -tailcallopt is intended to provide a guaranteed
|
||||||
@ -809,6 +810,19 @@ bool X86FastISel::X86SelectRet(const Instruction *I) {
|
|||||||
MRI.addLiveOut(VA.getLocReg());
|
MRI.addLiveOut(VA.getLocReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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()) {
|
||||||
|
unsigned Reg = X86MFInfo->getSRetReturnReg();
|
||||||
|
assert(Reg &&
|
||||||
|
"SRetReturnReg should have been set in LowerFormalArguments()!");
|
||||||
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY),
|
||||||
|
X86::RAX).addReg(Reg);
|
||||||
|
MRI.addLiveOut(X86::RAX);
|
||||||
|
}
|
||||||
|
|
||||||
// Now emit the RET.
|
// Now emit the RET.
|
||||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::RET));
|
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::RET));
|
||||||
return true;
|
return true;
|
||||||
|
@ -291,3 +291,16 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare void @foo22(i32)
|
declare void @foo22(i32)
|
||||||
|
|
||||||
|
; PR13563
|
||||||
|
define void @test23(i8* noalias sret %result) {
|
||||||
|
%a = alloca i8
|
||||||
|
%b = call i8* @foo23()
|
||||||
|
ret void
|
||||||
|
; CHECK: test23:
|
||||||
|
; CHECK: call
|
||||||
|
; CHECK: movq %rdi, %rax
|
||||||
|
; CHECK: ret
|
||||||
|
}
|
||||||
|
|
||||||
|
declare i8* @foo23()
|
||||||
|
Loading…
Reference in New Issue
Block a user