summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-12-08 23:58:27 +0000
committerChris Lattner <sabre@nondot.org>2007-12-08 23:58:27 +0000
commiteeaad40246e45ec48c85acac4ab57e82457abf19 (patch)
treeccab5a9c7f704b5af95b76b25f12ddcbcf988332
parent50187864c12dbf15f021cacfd6922d9c014f3f8d (diff)
downloadllvm-eeaad40246e45ec48c85acac4ab57e82457abf19.tar.gz
llvm-eeaad40246e45ec48c85acac4ab57e82457abf19.tar.bz2
llvm-eeaad40246e45ec48c85acac4ab57e82457abf19.tar.xz
add many new cases to SplitResult. SplitResult now handles all the cases that LegalizeDAG does.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44726 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h10
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp171
2 files changed, 178 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 3b7e26bab5..0ecc70f4af 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -276,7 +276,17 @@ private:
void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+ void SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+ void SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
// Operand Vector Scalarization: <128 x ty> -> 2 x <64 x ty>.
bool SplitOperand(SDNode *N, unsigned OpNo);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
index c9bf70a3bc..c16b05110d 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
@@ -71,8 +71,26 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
assert(0 && "Do not know how to split the result of this operator!");
abort();
- case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
- case ISD::LOAD: SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
+ case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
+ case ISD::LOAD: SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
+ case ISD::BUILD_PAIR: SplitRes_BUILD_PAIR(N, Lo, Hi); break;
+ case ISD::INSERT_VECTOR_ELT:SplitRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
+ case ISD::VECTOR_SHUFFLE: SplitRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
+ case ISD::BUILD_VECTOR: SplitRes_BUILD_VECTOR(N, Lo, Hi); break;
+ case ISD::CONCAT_VECTORS: SplitRes_CONCAT_VECTORS(N, Lo, Hi); break;
+ case ISD::BIT_CONVERT: SplitRes_BIT_CONVERT(N, Lo, Hi); break;
+ case ISD::CTTZ:
+ case ISD::CTLZ:
+ case ISD::CTPOP:
+ case ISD::FNEG:
+ case ISD::FABS:
+ case ISD::FSQRT:
+ case ISD::FSIN:
+ case ISD::FCOS:
+ case ISD::FP_TO_SINT:
+ case ISD::FP_TO_UINT:
+ case ISD::SINT_TO_FP:
+ case ISD::UINT_TO_FP: SplitRes_UnOp(N, Lo, Hi); break;
case ISD::ADD:
case ISD::SUB:
case ISD::MUL:
@@ -88,7 +106,9 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
case ISD::XOR:
case ISD::UREM:
case ISD::SREM:
- case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break;
+ case ISD::FREM: SplitRes_BinOp(N, Lo, Hi); break;
+ case ISD::FPOWI: SplitRes_FPOWI(N, Lo, Hi); break;
+ case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
}
// If Lo/Hi is null, the sub-method took care of registering results etc.
@@ -134,6 +154,124 @@ void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
ReplaceValueWith(SDOperand(LD, 1), TF);
}
+void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
+ Lo = N->getOperand(0);
+ Hi = N->getOperand(1);
+}
+
+void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
+ GetSplitOp(N->getOperand(0), Lo, Hi);
+ unsigned Index = cast<ConstantSDNode>(N->getOperand(2))->getValue();
+ SDOperand ScalarOp = N->getOperand(1);
+ unsigned LoNumElts = MVT::getVectorNumElements(Lo.getValueType());
+ if (Index < LoNumElts)
+ Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, ScalarOp,
+ N->getOperand(2));
+ else
+ Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, ScalarOp,
+ DAG.getConstant(Index - LoNumElts, TLI.getPointerTy()));
+
+}
+
+void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // Build the low part.
+ SDOperand Mask = N->getOperand(2);
+ SmallVector<SDOperand, 16> Ops;
+ MVT::ValueType PtrVT = TLI.getPointerTy();
+
+ MVT::ValueType LoVT, HiVT;
+ GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+ MVT::ValueType EltVT = MVT::getVectorElementType(LoVT);
+ unsigned LoNumElts = MVT::getVectorNumElements(LoVT);
+ unsigned NumElements = Mask.getNumOperands();
+
+ // Insert all of the elements from the input that are needed. We use
+ // buildvector of extractelement here because the input vectors will have
+ // to be legalized, so this makes the code simpler.
+ for (unsigned i = 0; i != LoNumElts; ++i) {
+ unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+ SDOperand InVec = N->getOperand(0);
+ if (Idx >= NumElements) {
+ InVec = N->getOperand(1);
+ Idx -= NumElements;
+ }
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
+ DAG.getConstant(Idx, PtrVT)));
+ }
+ Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &Ops[0], Ops.size());
+ Ops.clear();
+
+ for (unsigned i = LoNumElts; i != NumElements; ++i) {
+ unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+ SDOperand InVec = N->getOperand(0);
+ if (Idx >= NumElements) {
+ InVec = N->getOperand(1);
+ Idx -= NumElements;
+ }
+ Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
+ DAG.getConstant(Idx, PtrVT)));
+ }
+ Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size());
+}
+
+void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo,
+ SDOperand &Hi) {
+ MVT::ValueType LoVT, HiVT;
+ GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+ unsigned LoNumElts = MVT::getVectorNumElements(LoVT);
+ SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
+ Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size());
+
+ SmallVector<SDOperand, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
+ Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
+}
+
+void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // FIXME: Handle non-power-of-two vectors?
+ unsigned NumSubvectors = N->getNumOperands() / 2;
+ if (NumSubvectors == 1) {
+ Lo = N->getOperand(0);
+ Hi = N->getOperand(1);
+ return;
+ }
+
+ MVT::ValueType LoVT, HiVT;
+ GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+ SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
+ Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size());
+
+ SmallVector<SDOperand, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
+ Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
+}
+
+void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // We know the result is a vector. The input may be either a vector or a
+ // scalar value.
+ SDOperand InOp = N->getOperand(0);
+ if (MVT::isVector(InOp.getValueType()) &&
+ MVT::getVectorNumElements(InOp.getValueType()) != 1) {
+ // If this is a vector, split the vector and convert each of the pieces now.
+ GetSplitOp(InOp, Lo, Hi);
+
+ MVT::ValueType LoVT, HiVT;
+ GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+ Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+ return;
+ }
+
+ // Lower the bit-convert to a store/load from the stack, then split the load.
+ SDOperand Op = CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
+ SplitRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
+}
+
void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
SDOperand LHSLo, LHSHi;
GetSplitOp(N->getOperand(0), LHSLo, LHSHi);
@@ -144,6 +282,33 @@ void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
}
+void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+ // Get the dest types. This doesn't always match input types, e.g. int_to_fp.
+ MVT::ValueType LoVT, HiVT;
+ GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+ GetSplitOp(N->getOperand(0), Lo, Hi);
+ Lo = DAG.getNode(N->getOpcode(), LoVT, Lo);
+ Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
+}
+
+void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+ GetSplitOp(N->getOperand(0), Lo, Hi);
+ Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
+ Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1));
+}
+
+
+void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
+ SDOperand LL, LH, RL, RH;
+ GetSplitOp(N->getOperand(1), LL, LH);
+ GetSplitOp(N->getOperand(2), RL, RH);
+
+ SDOperand Cond = N->getOperand(0);
+ Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
+ Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
+}
+
//===----------------------------------------------------------------------===//
// Operand Vector Splitting