diff options
author | Duncan Sands <baldrick@free.fr> | 2008-02-20 17:38:09 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-02-20 17:38:09 +0000 |
commit | f83b1f63ddf27aaba791393940f37709ebbda33b (patch) | |
tree | eb1afeab9425b383c511324b79f3186c4472ea46 | |
parent | 91dc17ba4991e971c7e89e07642b10817aa28055 (diff) | |
download | external_llvm-f83b1f63ddf27aaba791393940f37709ebbda33b.zip external_llvm-f83b1f63ddf27aaba791393940f37709ebbda33b.tar.gz external_llvm-f83b1f63ddf27aaba791393940f37709ebbda33b.tar.bz2 |
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
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypes.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp | 23 | ||||
-rw-r--r-- | 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 acae44b..3ebc211 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 95306b9..da8fd80 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<StoreSDNode>(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 549afe9..489aea4 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<StoreSDNode>(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<ConstantSDNode>(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 ef28aa5..28f612d 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) { |