From fa9c5eac33bef67e2faef166c902e3bb16efa30f Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Thu, 15 Jan 2009 22:43:38 +0000 Subject: [PATCH] Added missing support to widen an operand from a bit convert. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62285 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 + .../SelectionDAG/LegalizeVectorTypes.cpp | 31 +++++++++++++++++++ test/CodeGen/X86/widen_cast-6.ll | 10 ++++++ 3 files changed, 42 insertions(+) create mode 100644 test/CodeGen/X86/widen_cast-6.ll diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index c6fbf70a342..949ee349ce2 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -606,6 +606,7 @@ private: // Widen Vector Operand. bool WidenVectorOperand(SDNode *N, unsigned ResNo); + SDValue WidenVecOp_BIT_CONVERT(SDNode *N); SDValue WidenVecOp_CONCAT_VECTORS(SDNode *N); SDValue WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N); SDValue WidenVecOp_STORE(SDNode* N); diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 0c2639a467e..3823f65263a 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -1735,6 +1735,7 @@ bool DAGTypeLegalizer::WidenVectorOperand(SDNode *N, unsigned ResNo) { assert(0 && "Do not know how to widen this operator's operand!"); abort(); + case ISD::BIT_CONVERT: Res = WidenVecOp_BIT_CONVERT(N); break; case ISD::CONCAT_VECTORS: Res = WidenVecOp_CONCAT_VECTORS(N); break; case ISD::EXTRACT_VECTOR_ELT: Res = WidenVecOp_EXTRACT_VECTOR_ELT(N); break; case ISD::STORE: Res = WidenVecOp_STORE(N); break; @@ -1786,6 +1787,36 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) { return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts); } +SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) { + MVT VT = N->getValueType(0); + SDValue InOp = GetWidenedVector(N->getOperand(0)); + MVT InWidenVT = InOp.getValueType(); + + // Check if we can convert between two legal vector types and extract. + unsigned InWidenSize = InWidenVT.getSizeInBits(); + unsigned Size = VT.getSizeInBits(); + if (InWidenSize % Size == 0 && !VT.isVector()) { + unsigned NewNumElts = InWidenSize / Size; + MVT NewVT = MVT::getVectorVT(VT, NewNumElts); + if (TLI.isTypeLegal(NewVT)) { + SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, NewVT, InOp); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, BitOp, + DAG.getIntPtrConstant(0)); + } + } + + // Lower the bit-convert to a store/load from the stack. Create the stack + // frame object. Make sure it is aligned for both the source and destination + // types. + SDValue FIPtr = DAG.CreateStackTemporary(InWidenVT, VT); + + // Emit a store to the stack slot. + SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0); + + // Result is a load from the stack slot. + return DAG.getLoad(VT, Store, FIPtr, NULL, 0); +} + SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { // If the input vector is not legal, it is likely that we will not find a // legal vector of the same size. Replace the concatenate vector with a diff --git a/test/CodeGen/X86/widen_cast-6.ll b/test/CodeGen/X86/widen_cast-6.ll new file mode 100644 index 00000000000..0fa1b7a7604 --- /dev/null +++ b/test/CodeGen/X86/widen_cast-6.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse41 -disable-mmx -o %t -f +; RUN: grep movd %t | count 1 + +; Test bit convert that requires widening in the operand. + +define i32 @return_v2hi() nounwind { +entry: + %retval12 = bitcast <2 x i16> zeroinitializer to i32 ; [#uses=1] + ret i32 %retval12 +} -- 2.34.1