diff options
author | Duncan Sands <baldrick@free.fr> | 2008-10-20 16:31:21 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-10-20 16:31:21 +0000 |
commit | d398672dddc50704ba7c4adbcf7dc99bd14c0108 (patch) | |
tree | cbdb1afd9993722e6c924246bc1b9a19038fd109 | |
parent | 9a2c1d3c46e6f24f978513244daad5c9b94e4556 (diff) |
Support operations like fp_to_uint with a vector
result type when the result type is legal but
not the operand type. Add additional support
for EXTRACT_SUBVECTOR and CONCAT_VECTORS,
needed to handle such cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57840 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 51 |
2 files changed, 53 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 21cad45d40..8e1fa1b342 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -416,6 +416,7 @@ private: SDValue ScalarizeVecRes_UnaryOp(SDNode *N); SDValue ScalarizeVecRes_BIT_CONVERT(SDNode *N); + SDValue ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N); SDValue ScalarizeVecRes_FPOWI(SDNode *N); SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N); SDValue ScalarizeVecRes_LOAD(LoadSDNode *N); @@ -427,6 +428,7 @@ private: // Vector Operand Scalarization: <1 x ty> -> ty. bool ScalarizeVectorOperand(SDNode *N, unsigned OpNo); SDValue ScalarizeVecOp_BIT_CONVERT(SDNode *N); + SDValue ScalarizeVecOp_CONCAT_VECTORS(SDNode *N); SDValue ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N); SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo); @@ -455,6 +457,7 @@ private: // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>. bool SplitVectorOperand(SDNode *N, unsigned OpNo); + SDValue SplitVecOp_UnaryOp(SDNode *N); SDValue SplitVecOp_BIT_CONVERT(SDNode *N); SDValue SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N); diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 54436f1563..0b9645db27 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -43,6 +43,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) { case ISD::BIT_CONVERT: R = ScalarizeVecRes_BIT_CONVERT(N); break; case ISD::BUILD_VECTOR: R = N->getOperand(0); break; + case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break; case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break; case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break; case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast<LoadSDNode>(N));break; @@ -67,6 +68,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) { case ISD::FRINT: case ISD::FNEARBYINT: case ISD::SINT_TO_FP: + case ISD::TRUNCATE: case ISD::UINT_TO_FP: R = ScalarizeVecRes_UnaryOp(N); break; case ISD::ADD: @@ -103,6 +105,12 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) { return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0)); } +SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) { + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, + N->getValueType(0).getVectorElementType(), + N->getOperand(0), N->getOperand(1)); +} + SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) { SDValue Op = GetScalarizedVector(N->getOperand(0)); return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); @@ -139,7 +147,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) { SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) { // Get the dest type - it doesn't always match the input type, e.g. int_to_fp. - MVT DestVT = TLI.getTypeToTransformTo(N->getValueType(0)); + MVT DestVT = N->getValueType(0).getVectorElementType(); SDValue Op = GetScalarizedVector(N->getOperand(0)); return DAG.getNode(N->getOpcode(), DestVT, Op); } @@ -199,6 +207,9 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) { case ISD::BIT_CONVERT: Res = ScalarizeVecOp_BIT_CONVERT(N); break; + case ISD::CONCAT_VECTORS: + Res = ScalarizeVecOp_CONCAT_VECTORS(N); break; + case ISD::EXTRACT_VECTOR_ELT: Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N); break; @@ -234,6 +245,16 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_BIT_CONVERT(SDNode *N) { return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt); } +/// ScalarizeVecOp_CONCAT_VECTORS - The vectors to concatenate have length one - +/// use a BUILD_VECTOR instead. +SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) { + SmallVector<SDValue, 8> Ops(N->getNumOperands()); + for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) + Ops[i] = GetScalarizedVector(N->getOperand(i)); + return DAG.getNode(ISD::BUILD_VECTOR, N->getValueType(0), + &Ops[0], Ops.size()); +} + /// ScalarizeVecOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to /// be scalarized, it must be <1 x ty>, so just return the element, ignoring the /// index. @@ -313,6 +334,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: case ISD::SINT_TO_FP: + case ISD::TRUNCATE: case ISD::UINT_TO_FP: SplitVecRes_UnaryOp(N, Lo, Hi); break; case ISD::ADD: @@ -636,6 +658,15 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) { case ISD::STORE: Res = SplitVecOp_STORE(cast<StoreSDNode>(N), OpNo); break; case ISD::VECTOR_SHUFFLE: Res = SplitVecOp_VECTOR_SHUFFLE(N, OpNo);break; + + case ISD::CTTZ: + case ISD::CTLZ: + case ISD::CTPOP: + case ISD::FP_TO_SINT: + case ISD::FP_TO_UINT: + case ISD::SINT_TO_FP: + case ISD::TRUNCATE: + case ISD::UINT_TO_FP: Res = SplitVecOp_UnaryOp(N); break; } } @@ -659,6 +690,24 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) { return false; } +SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) { + // The result has a legal vector type, but the input needs splitting. + MVT ResVT = N->getValueType(0); + SDValue Lo, Hi; + GetSplitVector(N->getOperand(0), Lo, Hi); + assert(Lo.getValueType() == Hi.getValueType() && + "Returns legal non-power-of-two vector type?"); + MVT InVT = Lo.getValueType(); + + MVT OutVT = MVT::getVectorVT(ResVT.getVectorElementType(), + InVT.getVectorNumElements()); + + Lo = DAG.getNode(N->getOpcode(), OutVT, Lo); + Hi = DAG.getNode(N->getOpcode(), OutVT, Hi); + + return DAG.getNode(ISD::CONCAT_VECTORS, ResVT, Lo, Hi); +} + SDValue DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) { // For example, i64 = BIT_CONVERT v4i16 on alpha. Typically the vector will // end up being split all the way down to individual components. Convert the |