From e4ffc030e2869bda17a9b9798092e929114863bd Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sun, 22 Feb 2009 08:05:12 +0000 Subject: [PATCH] Be bug compatible with gcc by returning MMX values in RAX. llvm-svn: 65274 --- llvm/lib/Target/X86/X86CallingConv.td | 5 +++-- llvm/lib/Target/X86/X86ISelLowering.cpp | 15 ++++++++++----- llvm/test/CodeGen/X86/ret-mmx.ll | 6 +++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index 6742a90058a2..80bdbd0b1cfa 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -72,8 +72,9 @@ def RetCC_X86_64_C : CallingConv<[ CCIfType<[f32], CCAssignToReg<[XMM0, XMM1]>>, CCIfType<[f64], CCAssignToReg<[XMM0, XMM1]>>, - // MMX vector types are always returned in XMM0. - CCIfType<[v8i8, v4i16, v2i32, v1i64, v2f32], CCAssignToReg<[XMM0, XMM1]>>, + // MMX vector types are always returned in RAX. This seems to disagree with + // ABI documentation but is bug compatible with gcc. + CCIfType<[v8i8, v4i16, v2i32, v1i64, v2f32], CCAssignToReg<[RAX]>>, CCDelegateTo ]>; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index efcb3f47ff77..674a633244d5 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -997,6 +997,14 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { continue; } + // 64-bit vector (MMX) values are returned in RAX. + if (Subtarget->is64Bit()) { + MVT ValVT = ValToCopy.getValueType(); + if (VA.getLocReg() == X86::RAX && + ValVT.isVector() && ValVT.getSizeInBits() == 64) + ValToCopy = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i64, ValToCopy); + } + Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), ValToCopy, Flag); Flag = Chain.getValue(1); } @@ -1073,13 +1081,10 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, 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. + // For x86-64, MMX values are returned in RAX. Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), - MVT::v2i64, InFlag).getValue(1); + MVT::i64, 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(), diff --git a/llvm/test/CodeGen/X86/ret-mmx.ll b/llvm/test/CodeGen/X86/ret-mmx.ll index fe9380585de3..6587eabb7665 100644 --- a/llvm/test/CodeGen/X86/ret-mmx.ll +++ b/llvm/test/CodeGen/X86/ret-mmx.ll @@ -3,11 +3,15 @@ @g_v1di = external global <1 x i64> -define void @test_v1di() nounwind { +define void @t1() 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 } +define <1 x i64> @t2() nounwind { + ret <1 x i64> +} + declare <1 x i64> @return_v1di() -- GitLab