From f8fc892b6c9278fd6c8cc2d1562fe9bdbd346b9a Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Tue, 2 Oct 2012 22:45:06 +0000 Subject: [PATCH] Make sure to put our sret argument into %rax on x86-64. Fixes PR13563! llvm-svn: 165063 --- llvm/lib/Target/X86/X86FastISel.cpp | 18 ++++++++++++++++-- llvm/test/CodeGen/X86/fast-isel-x86-64.ll | 13 +++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index 83f2f6a202bc..2a8bf8194176 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -710,6 +710,8 @@ bool X86FastISel::X86SelectStore(const Instruction *I) { bool X86FastISel::X86SelectRet(const Instruction *I) { const ReturnInst *Ret = cast(I); const Function &F = *I->getParent()->getParent(); + const X86MachineFunctionInfo *X86MFInfo = + FuncInfo.MF->getInfo(); if (!FuncInfo.CanLowerReturn) return false; @@ -724,8 +726,7 @@ bool X86FastISel::X86SelectRet(const Instruction *I) { return false; // Don't handle popping bytes on return for now. - if (FuncInfo.MF->getInfo() - ->getBytesToPopOnReturn() != 0) + if (X86MFInfo->getBytesToPopOnReturn() != 0) return 0; // fastcc with -tailcallopt is intended to provide a guaranteed @@ -809,6 +810,19 @@ bool X86FastISel::X86SelectRet(const Instruction *I) { 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. BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(X86::RET)); return true; diff --git a/llvm/test/CodeGen/X86/fast-isel-x86-64.ll b/llvm/test/CodeGen/X86/fast-isel-x86-64.ll index 85a70aad7590..cdfaf7f4c134 100644 --- a/llvm/test/CodeGen/X86/fast-isel-x86-64.ll +++ b/llvm/test/CodeGen/X86/fast-isel-x86-64.ll @@ -291,3 +291,16 @@ entry: } 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()