From f83b1f63ddf27aaba791393940f37709ebbda33b Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Wed, 20 Feb 2008 17:38:09 +0000 Subject: [PATCH] LegalizeTypes support for scalarizing a vector store and splitting extract_subvector. This fixes nine "make check" testcases, for example 2008-02-04-ExtractSubvector.ll and (partially) CodeGen/Generic/vector.ll. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47384 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeTypes.h | 8 +++++--- .../SelectionDAG/LegalizeTypesScalarize.cpp | 19 +++++++++++++----- lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp | 23 ++++++++++++++++++++++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 ++++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index acae44b2ac1..3ebc2110587 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -275,7 +275,8 @@ private: // Operand Vector Scalarization: <1 x ty> -> ty. bool ScalarizeOperand(SDNode *N, unsigned OpNo); - SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, unsigned OpNo); + SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N); + SDOperand ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo); //===--------------------------------------------------------------------===// // Vector Splitting Support: LegalizeTypesSplit.cpp @@ -303,9 +304,10 @@ private: // Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>. bool SplitOperand(SDNode *N, unsigned OpNo); - - SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo); + + SDOperand SplitOp_EXTRACT_SUBVECTOR(SDNode *N); SDOperand SplitOp_RET(SDNode *N, unsigned OpNo); + SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo); }; } // end namespace llvm. diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp index 95306b99fab..da8fd807a4e 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp @@ -166,8 +166,10 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { abort(); case ISD::EXTRACT_VECTOR_ELT: - Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N, OpNo); - break; + Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break; + + case ISD::STORE: + Res = ScalarizeOp_STORE(cast(N), OpNo); break; } } @@ -193,10 +195,17 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { } /// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be -/// scalarized, it must be <1 x ty>, just return the operand, ignoring the +/// scalarized, it must be <1 x ty>, so just return the element, ignoring the /// index. -SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N, - unsigned OpNo) { +SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) { return GetScalarizedOp(N->getOperand(0)); } +/// ScalarizeOp_STORE - If the value to store is a vector that needs to be +/// scalarized, it must be <1 x ty>. Just store the element. +SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) { + assert(OpNo == 1 && "Do not know how to scalarize this operand!"); + return DAG.getStore(N->getChain(), GetScalarizedOp(N->getOperand(1)), + N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(), + N->isVolatile(), N->getAlignment()); +} diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp index 549afe9c6f4..489aea4c64c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp @@ -339,6 +339,8 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) { abort(); case ISD::STORE: Res = SplitOp_STORE(cast(N), OpNo); break; case ISD::RET: Res = SplitOp_RET(N, OpNo); break; + + case ISD::EXTRACT_SUBVECTOR: Res = SplitOp_EXTRACT_SUBVECTOR(N); break; } } @@ -399,3 +401,24 @@ SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) { return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign); } + +SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) { + // We know that the extracted result type is legal. For now, assume the index + // is a constant. + MVT::ValueType SubVT = N->getValueType(0); + SDOperand Idx = N->getOperand(1); + SDOperand Lo, Hi; + GetSplitOp(N->getOperand(0), Lo, Hi); + + uint64_t LoElts = MVT::getVectorNumElements(Lo.getValueType()); + uint64_t IdxVal = cast(Idx)->getValue(); + + if (IdxVal < LoElts) { + assert(IdxVal + MVT::getVectorNumElements(SubVT) <= LoElts && + "Extracted subvector crosses vector split!"); + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Lo, Idx); + } else { + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Hi, + DAG.getConstant(IdxVal - LoElts, Idx.getValueType())); + } +} diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ef28aa5a2b4..28f612d8cd1 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2145,6 +2145,10 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, return getConstant(C->getValue() >> Shift, VT); } break; + case ISD::EXTRACT_SUBVECTOR: + if (N1.getValueType() == VT) // Trivial extraction. + return N1; + break; } if (N1C) { -- 2.11.0