From f10d3a7bcda97d28f9d325cb58cec7e17d7ed101 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 7 Jun 2009 09:41:57 +0000 Subject: [PATCH] Tweak the expansion code for BIT_CONVERT to generate better code converting from an MMX vector to an i64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73024 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/LegalizeTypesGeneric.cpp | 20 +++++++++++++++++++ .../X86/2009-06-07-ExpandMMXBitcast.ll | 10 ++++++++++ 2 files changed, 30 insertions(+) create mode 100644 test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index e8ff3fc9efb..b7d7818d6e0 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -92,6 +92,26 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, } } + if (InVT.isVector() && OutVT.isInteger()) { + // Handle cases like i64 = BIT_CONVERT v1i64 on x86, where the operand + // is legal but the result is not. + MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OutVT), 2); + + if (isTypeLegal(NVT)) { + SDValue CastInOp = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, InOp); + MVT EltNVT = NVT.getVectorElementType(); + Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltNVT, CastInOp, + DAG.getIntPtrConstant(0)); + Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltNVT, CastInOp, + DAG.getIntPtrConstant(1)); + + if (TLI.isBigEndian()) + std::swap(Lo, Hi); + + return; + } + } + // Lower the bit-convert to a store/load from the stack. assert(NOutVT.isByteSized() && "Expanded type not byte sized!"); diff --git a/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll b/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll new file mode 100644 index 00000000000..56015c6473b --- /dev/null +++ b/test/CodeGen/X86/2009-06-07-ExpandMMXBitcast.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc | grep movl | count 2 + +define i64 @a(i32 %a, i32 %b) nounwind readnone { +entry: + %0 = insertelement <2 x i32> undef, i32 %a, i32 0 ; <<2 x i32>> [#uses=1] + %1 = insertelement <2 x i32> %0, i32 %b, i32 1 ; <<2 x i32>> [#uses=1] + %conv = bitcast <2 x i32> %1 to i64 ; [#uses=1] + ret i64 %conv +} +