From 79fb3b434f83bcb7c382dbcfea485884a39b9544 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 20 Feb 2009 20:43:02 +0000 Subject: [PATCH] Support return of MMX values in 64-bit mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65152 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 18 +++++++++++++++--- test/CodeGen/X86/ret-mmx.ll | 13 +++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/X86/ret-mmx.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 85a6c0bb9bd..efcb3f47ff7 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1071,9 +1071,21 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, CopyVT = MVT::f80; } - Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), - CopyVT, InFlag).getValue(1); - SDValue Val = Chain.getValue(0); + SDValue Val; + if (Is64Bit && CopyVT.isVector() && CopyVT.getSizeInBits() == 64) { + // For x86-64, MMX values are returned in XMM0 and XMM1. Issue an + // extract_vector_elt to i64 and then bit_convert it to the desired type. + Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), + MVT::v2i64, InFlag).getValue(1); + Val = Chain.getValue(0); + Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::i64, + Val, DAG.getConstant(0, MVT::i64)); + Val = DAG.getNode(ISD::BIT_CONVERT, dl, CopyVT, Val); + } else { + Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), + CopyVT, InFlag).getValue(1); + Val = Chain.getValue(0); + } InFlag = Chain.getValue(2); if (CopyVT != VA.getValVT()) { diff --git a/test/CodeGen/X86/ret-mmx.ll b/test/CodeGen/X86/ret-mmx.ll new file mode 100644 index 00000000000..fe9380585de --- /dev/null +++ b/test/CodeGen/X86/ret-mmx.ll @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llc -march=x86-64 -mattr=+mmx +; rdar://6602459 + +@g_v1di = external global <1 x i64> + +define void @test_v1di() nounwind { +entry: + %call = call <1 x i64> @return_v1di() ; <<1 x i64>> [#uses=0] + store <1 x i64> %call, <1 x i64>* @g_v1di + ret void +} + +declare <1 x i64> @return_v1di()