diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 6de82f7add1..2a36ae21d57 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -14,7 +14,7 @@ // The resulting integer value is the same as what you would get by performing // the floating point operation and bitcasting the result to the integer type. // Expansion is the act of changing a computation in an illegal type to be a -// computation in multiple registers of a smaller type. For example, +// computation in two identical registers of a smaller type. For example, // implementing ppcf128 arithmetic in two f64 registers. // //===----------------------------------------------------------------------===// @@ -395,6 +395,15 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { #endif assert(0 && "Do not know how to expand the result of this operator!"); abort(); + + case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; + case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; + case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; + case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; + + case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; + case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; + case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -428,6 +437,10 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { #endif assert(0 && "Do not know how to expand this operator's operand!"); abort(); + + case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; + case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; + case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; } } diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 481d9bea4c1..90b800e14f7 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -12,7 +12,7 @@ // computation in a larger type. For example, implementing i8 arithmetic in an // i32 register (often needed on powerpc). // Expansion is the act of changing a computation in an illegal type into a -// computation in multiple registers of a smaller type. For example, +// computation in two identical registers of a smaller type. For example, // implementing i64 arithmetic in two i32 registers (often needed on 32-bit // targets). // @@ -753,19 +753,24 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { cerr << "ExpandIntegerResult #" << ResNo << ": "; N->dump(&DAG); cerr << "\n"; #endif - assert(0&&"Do not know how to expand the result of this operator!"); + assert(0 && "Do not know how to expand the result of this operator!"); abort(); - case ISD::UNDEF: ExpandIntRes_UNDEF(N, Lo, Hi); break; + case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; + case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; + case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; + case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; + + case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; + case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; + case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; + case ISD::Constant: ExpandIntRes_Constant(N, Lo, Hi); break; - case ISD::BUILD_PAIR: ExpandIntRes_BUILD_PAIR(N, Lo, Hi); break; - case ISD::MERGE_VALUES: ExpandIntRes_MERGE_VALUES(N, Lo, Hi); break; case ISD::ANY_EXTEND: ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break; case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break; case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break; case ISD::AssertZext: ExpandIntRes_AssertZext(N, Lo, Hi); break; case ISD::TRUNCATE: ExpandIntRes_TRUNCATE(N, Lo, Hi); break; - case ISD::BIT_CONVERT: ExpandIntRes_BIT_CONVERT(N, Lo, Hi); break; case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break; case ISD::FP_TO_SINT: ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break; case ISD::FP_TO_UINT: ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break; @@ -781,8 +786,6 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { case ISD::SUBC: ExpandIntRes_ADDSUBC(N, Lo, Hi); break; case ISD::ADDE: case ISD::SUBE: ExpandIntRes_ADDSUBE(N, Lo, Hi); break; - case ISD::SELECT: ExpandIntRes_SELECT(N, Lo, Hi); break; - case ISD::SELECT_CC: ExpandIntRes_SELECT_CC(N, Lo, Hi); break; case ISD::MUL: ExpandIntRes_MUL(N, Lo, Hi); break; case ISD::SDIV: ExpandIntRes_SDIV(N, Lo, Hi); break; case ISD::SREM: ExpandIntRes_SREM(N, Lo, Hi); break; @@ -795,10 +798,6 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { case ISD::CTLZ: ExpandIntRes_CTLZ(N, Lo, Hi); break; case ISD::CTPOP: ExpandIntRes_CTPOP(N, Lo, Hi); break; case ISD::CTTZ: ExpandIntRes_CTTZ(N, Lo, Hi); break; - - case ISD::EXTRACT_VECTOR_ELT: - ExpandIntRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); - break; } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -806,12 +805,6 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { SetExpandedInteger(SDOperand(N, ResNo), Lo, Hi); } -void DAGTypeLegalizer::ExpandIntRes_UNDEF(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - Lo = Hi = DAG.getNode(ISD::UNDEF, NVT); -} - void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N, SDOperand &Lo, SDOperand &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); @@ -821,34 +814,6 @@ void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N, Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT); } -void DAGTypeLegalizer::ExpandIntRes_BUILD_PAIR(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // Return the operands. - Lo = N->getOperand(0); - Hi = N->getOperand(1); -} - -void DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - // A MERGE_VALUES node can produce any number of values. We know that the - // first illegal one needs to be expanded into Lo/Hi. - unsigned i; - - // The string of legal results gets turns into the input operands, which have - // the same type. - for (i = 0; isTypeLegal(N->getValueType(i)); ++i) - ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); - - // The first illegal result must be the one that needs to be expanded. - GetExpandedInteger(N->getOperand(i), Lo, Hi); - - // Legalize the rest of the results into the input operands whether they are - // legal or not. - unsigned e = N->getNumValues(); - for (++i; i != e; ++i) - ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); -} - void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); @@ -950,61 +915,6 @@ void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N, Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi); } -void DAGTypeLegalizer::ExpandIntRes_BIT_CONVERT(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand InOp = N->getOperand(0); - MVT InVT = InOp.getValueType(); - - // Handle some special cases efficiently. - switch (getTypeAction(InVT)) { - default: - assert(false && "Unknown type action!"); - case Legal: - case PromoteInteger: - break; - case SoftenFloat: - // Convert the integer operand instead. - SplitInteger(GetSoftenedFloat(InOp), Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); - return; - case ExpandInteger: - // Convert the expanded pieces of the input. - GetExpandedInteger(InOp, Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); - return; - case ExpandFloat: - // Convert the expanded pieces of the input. - GetExpandedFloat(InOp, Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); - return; - case Split: - // Convert the split parts of the input if it was split in two. - GetSplitVector(InOp, Lo, Hi); - if (Lo.getValueType() == Hi.getValueType()) { - if (TLI.isBigEndian()) - std::swap(Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); - return; - } - break; - case Scalarize: - // Convert the element instead. - SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); - return; - } - - // Lower the bit-convert to a store/load from the stack, then expand the load. - SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0)); - ExpandIntRes_LOAD(cast(Op.Val), Lo, Hi); -} - void DAGTypeLegalizer:: ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) { GetExpandedInteger(N->getOperand(0), Lo, Hi); @@ -1090,7 +1000,13 @@ void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDOperand &Lo, void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi) { - // FIXME: Add support for indexed loads. + if (ISD::isNON_EXTLoad(N)) { + ExpandRes_NON_EXTLOAD(N, Lo, Hi); + return; + } + + assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); + MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); SDOperand Ch = N->getChain(); // Legalize the chain. @@ -1100,27 +1016,9 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); - assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!"); + assert(NVT.isByteSized() && "Expanded type not byte sized!"); - if (ExtType == ISD::NON_EXTLOAD) { - Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, - isVolatile, Alignment); - // Increment the pointer to the other half. - unsigned IncrementSize = NVT.getSizeInBits()/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - DAG.getIntPtrConstant(IncrementSize)); - Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); - - // Build a factor node to remember that this load is independent of the - // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), - Hi.getValue(1)); - - // Handle endianness of the load. - if (TLI.isBigEndian()) - std::swap(Lo, Hi); - } else if (N->getMemoryVT().bitsLE(NVT)) { + if (N->getMemoryVT().bitsLE(NVT)) { MVT EVT = N->getMemoryVT(); Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT, @@ -1225,26 +1123,6 @@ void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N, Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi); } -void DAGTypeLegalizer::ExpandIntRes_SELECT(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedInteger(N->getOperand(1), LL, LH); - GetExpandedInteger(N->getOperand(2), RL, RH); - Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL); - Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH); -} - -void DAGTypeLegalizer::ExpandIntRes_SELECT_CC(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { - SDOperand LL, LH, RL, RH; - GetExpandedInteger(N->getOperand(2), LL, LH); - GetExpandedInteger(N->getOperand(3), RL, RH); - Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), - N->getOperand(1), LL, RL, N->getOperand(4)); - Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), - N->getOperand(1), LH, RH, N->getOperand(4)); -} - void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, SDOperand &Lo, SDOperand &Hi) { // Expand the subcomponents. @@ -1522,41 +1400,6 @@ void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N, Hi = DAG.getConstant(0, NVT); } -void DAGTypeLegalizer::ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N, - SDOperand &Lo, - SDOperand &Hi) { - SDOperand OldVec = N->getOperand(0); - unsigned OldElts = OldVec.getValueType().getVectorNumElements(); - - // Convert to a vector of the expanded element type, for example - // <2 x i64> -> <4 x i32>. - MVT OldVT = N->getValueType(0); - MVT NewVT = TLI.getTypeToTransformTo(OldVT); - assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() && - "Do not know how to handle this expansion!"); - - SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT, - MVT::getVectorVT(NewVT, 2*OldElts), - OldVec); - - // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector. - SDOperand Idx = N->getOperand(1); - - // Make sure the type of Idx is big enough to hold the new values. - if (Idx.getValueType().bitsLT(TLI.getPointerTy())) - Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx); - - Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx); - Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx); - - Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, - DAG.getConstant(1, Idx.getValueType())); - Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx); - - if (TLI.isBigEndian()) - std::swap(Lo, Hi); -} - /// ExpandShiftByConstant - N is a shift by a value that needs to be expanded, /// and the shift amount is a constant 'Amt'. Expand the operation. void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, @@ -1737,8 +1580,11 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { assert(0 && "Do not know how to expand this operator's operand!"); abort(); + case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; + case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; + case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; + case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; - case ISD::BIT_CONVERT: Res = ExpandIntOp_BIT_CONVERT(N); break; case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N->getOperand(0), N->getValueType(0)); @@ -1746,7 +1592,6 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N->getOperand(0), N->getValueType(0)); break; - case ISD::EXTRACT_ELEMENT: Res = ExpandIntOp_EXTRACT_ELEMENT(N); break; case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break; case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break; @@ -1754,8 +1599,6 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::STORE: Res = ExpandIntOp_STORE(cast(N), OpNo); break; - - case ISD::BUILD_VECTOR: Res = ExpandIntOp_BUILD_VECTOR(N); break; } } @@ -1785,32 +1628,6 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) { return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL); } -SDOperand DAGTypeLegalizer::ExpandIntOp_BIT_CONVERT(SDNode *N) { - if (N->getValueType(0).isVector()) { - // An illegal integer type is being converted to a legal vector type. - // Make a two element vector out of the expanded parts and convert that - // instead, but only if the new vector type is legal (otherwise there - // is no point, and it might create expansion loops). For example, on - // x86 this turns v1i64 = BIT_CONVERT i64 into v1i64 = BIT_CONVERT v2i32. - MVT OVT = N->getOperand(0).getValueType(); - MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OVT), 2); - - if (isTypeLegal(NVT)) { - SDOperand Parts[2]; - GetExpandedInteger(N->getOperand(0), Parts[0], Parts[1]); - - if (TLI.isBigEndian()) - std::swap(Parts[0], Parts[1]); - - SDOperand Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2); - return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec); - } - } - - // Otherwise, store to a temporary and load out again as the new type. - return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); -} - SDOperand DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDOperand Source, MVT DestTy) { // We know the destination is legal, but that the input needs to be expanded. @@ -1898,12 +1715,6 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDOperand Source, return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg); } -SDOperand DAGTypeLegalizer::ExpandIntOp_EXTRACT_ELEMENT(SDNode *N) { - SDOperand Lo, Hi; - GetExpandedInteger(N->getOperand(0), Lo, Hi); - return cast(N->getOperand(1))->getValue() ? Hi : Lo; -} - SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) { SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); ISD::CondCode CCCode = cast(N->getOperand(1))->get(); @@ -2049,7 +1860,10 @@ void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, } SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { - // FIXME: Add support for indexed stores. + if (ISD::isNON_TRUNCStore(N)) + return ExpandOp_NON_TRUNCStore(N, OpNo); + + assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); assert(OpNo == 1 && "Can only expand the stored value so far"); MVT VT = N->getOperand(1).getValueType(); @@ -2063,24 +1877,7 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!"); - if (!N->isTruncatingStore()) { - unsigned IncrementSize = 0; - GetExpandedInteger(N->getValue(), Lo, Hi); - IncrementSize = Hi.getValueType().getSizeInBits()/8; - - if (TLI.isBigEndian()) - std::swap(Lo, Hi); - - Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), - SVOffset, isVolatile, Alignment); - - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, - DAG.getIntPtrConstant(IncrementSize)); - assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); - Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); - } else if (N->getMemoryVT().bitsLE(NVT)) { + if (N->getMemoryVT().bitsLE(NVT)) { GetExpandedInteger(N->getValue(), Lo, Hi); return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, N->getMemoryVT(), isVolatile, Alignment); @@ -2140,35 +1937,3 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); } } - -SDOperand DAGTypeLegalizer::ExpandIntOp_BUILD_VECTOR(SDNode *N) { - // The vector type is legal but the element type needs expansion. - MVT VecVT = N->getValueType(0); - unsigned NumElts = VecVT.getVectorNumElements(); - MVT OldVT = N->getOperand(0).getValueType(); - MVT NewVT = TLI.getTypeToTransformTo(OldVT); - - assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() && - "Do not know how to expand this operand!"); - - // Build a vector of twice the length out of the expanded elements. - // For example <2 x i64> -> <4 x i32>. - std::vector NewElts; - NewElts.reserve(NumElts*2); - - for (unsigned i = 0; i < NumElts; ++i) { - SDOperand Lo, Hi; - GetExpandedInteger(N->getOperand(i), Lo, Hi); - if (TLI.isBigEndian()) - std::swap(Lo, Hi); - NewElts.push_back(Lo); - NewElts.push_back(Hi); - } - - SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR, - MVT::getVectorVT(NewVT, NewElts.size()), - &NewElts[0], NewElts.size()); - - // Convert the new vector to the old vector type. - return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec); -} diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 6d150251da6..0c50d64d4e2 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -543,6 +543,10 @@ void DAGTypeLegalizer::SetSplitVector(SDOperand Op, SDOperand Lo, } +//===----------------------------------------------------------------------===// +// Utilities. +//===----------------------------------------------------------------------===// + /// BitConvertToInteger - Convert to an integer of the same size. SDOperand DAGTypeLegalizer::BitConvertToInteger(SDOperand Op) { unsigned BitWidth = Op.getValueType().getSizeInBits(); @@ -637,6 +641,26 @@ SDOperand DAGTypeLegalizer::GetVectorElementPointer(SDOperand VecPtr, MVT EltVT, return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr); } +/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type +/// which is split into two not necessarily identical pieces. +void DAGTypeLegalizer::GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT) { + if (!InVT.isVector()) { + LoVT = HiVT = TLI.getTypeToTransformTo(InVT); + } else { + MVT NewEltVT = InVT.getVectorElementType(); + unsigned NumElements = InVT.getVectorNumElements(); + if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector. + NumElements >>= 1; + LoVT = HiVT = MVT::getVectorVT(NewEltVT, NumElements); + } else { // Non-power-of-two vectors. + unsigned NewNumElts_Lo = 1 << Log2_32(NumElements); + unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; + LoVT = MVT::getVectorVT(NewEltVT, NewNumElts_Lo); + HiVT = MVT::getVectorVT(NewEltVT, NewNumElts_Hi); + } + } +} + //===----------------------------------------------------------------------===// // Entry Point diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 58e7b0e3e84..677aef4a8b2 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -267,19 +267,14 @@ private: void ExpandIntegerResult(SDNode *N, unsigned ResNo); void ExpandIntRes_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_AssertZext (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandIntRes_BIT_CONVERT (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandIntRes_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_CTLZ (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_CTPOP (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_CTTZ (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_LOAD (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandIntRes_MERGE_VALUES (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_SIGN_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_SIGN_EXTEND_INREG (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_TRUNCATE (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandIntRes_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_ZERO_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_FP_TO_SINT (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_FP_TO_UINT (SDNode *N, SDOperand &Lo, SDOperand &Hi); @@ -289,8 +284,6 @@ private: void ExpandIntRes_ADDSUB (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_ADDSUBC (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_ADDSUBE (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandIntRes_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi); - void ExpandIntRes_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_MUL (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_SDIV (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandIntRes_SREM (SDNode *N, SDOperand &Lo, SDOperand &Hi); @@ -372,22 +365,22 @@ private: // Vector Result Scalarization: <1 x ty> -> ty. void ScalarizeResult(SDNode *N, unsigned OpNo); - SDOperand ScalarizeRes_BinOp(SDNode *N); - SDOperand ScalarizeRes_UnaryOp(SDNode *N); + SDOperand ScalarizeVecRes_BinOp(SDNode *N); + SDOperand ScalarizeVecRes_UnaryOp(SDNode *N); - SDOperand ScalarizeRes_BIT_CONVERT(SDNode *N); - SDOperand ScalarizeRes_FPOWI(SDNode *N); - SDOperand ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N); - SDOperand ScalarizeRes_LOAD(LoadSDNode *N); - SDOperand ScalarizeRes_SELECT(SDNode *N); - SDOperand ScalarizeRes_UNDEF(SDNode *N); - SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N); + SDOperand ScalarizeVecRes_BIT_CONVERT(SDNode *N); + SDOperand ScalarizeVecRes_FPOWI(SDNode *N); + SDOperand ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N); + SDOperand ScalarizeVecRes_LOAD(LoadSDNode *N); + SDOperand ScalarizeVecRes_SELECT(SDNode *N); + SDOperand ScalarizeVecRes_UNDEF(SDNode *N); + SDOperand ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N); // Vector Operand Scalarization: <1 x ty> -> ty. bool ScalarizeOperand(SDNode *N, unsigned OpNo); - SDOperand ScalarizeOp_BIT_CONVERT(SDNode *N); - SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N); - SDOperand ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo); + SDOperand ScalarizeVecOp_BIT_CONVERT(SDNode *N); + SDOperand ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N); + SDOperand ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo); //===--------------------------------------------------------------------===// // Vector Splitting Support: LegalizeVectorTypes.cpp @@ -399,29 +392,85 @@ private: // Vector Result Splitting: <128 x ty> -> 2 x <64 x ty>. void SplitResult(SDNode *N, unsigned OpNo); - 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 SplitVecRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_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); + void SplitVecRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitVecRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi); // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>. bool SplitOperand(SDNode *N, unsigned OpNo); - SDOperand SplitOp_BIT_CONVERT(SDNode *N); - SDOperand SplitOp_EXTRACT_SUBVECTOR(SDNode *N); - SDOperand SplitOp_EXTRACT_VECTOR_ELT(SDNode *N); - SDOperand SplitOp_RET(SDNode *N, unsigned OpNo); - SDOperand SplitOp_STORE(StoreSDNode *N, unsigned OpNo); - SDOperand SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo); + SDOperand SplitVecOp_BIT_CONVERT(SDNode *N); + SDOperand SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N); + SDOperand SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N); + SDOperand SplitVecOp_RET(SDNode *N, unsigned OpNo); + SDOperand SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo); + SDOperand SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo); + + //===--------------------------------------------------------------------===// + // Generic Splitting: LegalizeTypesGeneric.cpp + //===--------------------------------------------------------------------===// + + // Legalization methods which only use that the illegal type is split into two + // not necessarily identical types. As such they can be used for splitting + // vectors and expanding integers and floats. + + void GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { + if (Op.getValueType().isVector()) + GetSplitVector(Op, Lo, Hi); + else if (Op.getValueType().isInteger()) + GetExpandedInteger(Op, Lo, Hi); + else + GetExpandedFloat(Op, Lo, Hi); + } + + /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type + /// which is split (or expanded) into two not necessarily identical pieces. + void GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT); + + // Generic Result Splitting. + void SplitRes_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_SELECT (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_SELECT_CC (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void SplitRes_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi); + + //===--------------------------------------------------------------------===// + // Generic Expansion: LegalizeTypesGeneric.cpp + //===--------------------------------------------------------------------===// + + // Legalization methods which only use that the illegal type is split into two + // identical types of half the size, and that the Lo/Hi part is stored first + // in memory on little/big-endian machines, followed by the Hi/Lo part. As + // such they can be used for expanding integers and floats. + + void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { + if (Op.getValueType().isInteger()) + GetExpandedInteger(Op, Lo, Hi); + else + GetExpandedFloat(Op, Lo, Hi); + } + + // Generic Result Expansion. + void ExpandRes_BIT_CONVERT (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandRes_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandRes_NON_EXTLOAD (SDNode *N, SDOperand &Lo, SDOperand &Hi); + + // Generic Operand Expansion. + SDOperand ExpandOp_BIT_CONVERT (SDNode *N); + SDOperand ExpandOp_BUILD_VECTOR (SDNode *N); + SDOperand ExpandOp_EXTRACT_ELEMENT(SDNode *N); + SDOperand ExpandOp_NON_TRUNCStore (SDNode *N, unsigned OpNo); + }; } // end namespace llvm. diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp new file mode 100644 index 00000000000..1b2ecef16d9 --- /dev/null +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -0,0 +1,318 @@ +//===-------- LegalizeTypesGeneric.cpp - Generic type legalization --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements generic type expansion and splitting for LegalizeTypes. +// The routines here perform legalization when the details of the type (such as +// whether it is an integer or a float) do not matter. +// Expansion is the act of changing a computation in an illegal type to be a +// computation in two identical registers of a smaller type. +// Splitting is the act of changing a computation in an illegal type to be a +// computation in two not necessarily identical registers of a smaller type. +// +//===----------------------------------------------------------------------===// + +#include "LegalizeTypes.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Generic Result Expansion. +//===----------------------------------------------------------------------===// + +// These routines assume that the Lo/Hi part is stored first in memory on +// little/big-endian machines, followed by the Hi/Lo part. This means that +// they cannot be used as is on vectors, for which Lo is always stored first. + +void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDOperand InOp = N->getOperand(0); + MVT InVT = InOp.getValueType(); + + // Handle some special cases efficiently. + switch (getTypeAction(InVT)) { + default: + assert(false && "Unknown type action!"); + case Legal: + case PromoteInteger: + break; + case SoftenFloat: + // Convert the integer operand instead. + SplitInteger(GetSoftenedFloat(InOp), Lo, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + return; + case ExpandInteger: + case ExpandFloat: + // Convert the expanded pieces of the input. + GetExpandedOp(InOp, Lo, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + return; + case Split: + // Convert the split parts of the input if it was split in two. + GetSplitVector(InOp, Lo, Hi); + if (Lo.getValueType() == Hi.getValueType()) { + if (TLI.isBigEndian()) + std::swap(Lo, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + return; + } + break; + case Scalarize: + // Convert the element instead. + SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi); + return; + } + + // Lower the bit-convert to a store/load from the stack, then expand the load. + SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0)); + ExpandRes_NON_EXTLOAD(Op.Val, Lo, Hi); +} + +void DAGTypeLegalizer::ExpandRes_BUILD_PAIR(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // Return the operands. + Lo = N->getOperand(0); + Hi = N->getOperand(1); +} + +void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, + SDOperand &Lo, + SDOperand &Hi) { + SDOperand OldVec = N->getOperand(0); + unsigned OldElts = OldVec.getValueType().getVectorNumElements(); + + // Convert to a vector of the expanded element type, for example + // <3 x i64> -> <6 x i32>. + MVT OldVT = N->getValueType(0); + MVT NewVT = TLI.getTypeToTransformTo(OldVT); + + SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT, + MVT::getVectorVT(NewVT, 2*OldElts), + OldVec); + + // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector. + SDOperand Idx = N->getOperand(1); + + // Make sure the type of Idx is big enough to hold the new values. + if (Idx.getValueType().bitsLT(TLI.getPointerTy())) + Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx); + + Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx); + Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx); + + Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, + DAG.getConstant(1, Idx.getValueType())); + Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx); + + if (TLI.isBigEndian()) + std::swap(Lo, Hi); +} + +void DAGTypeLegalizer::ExpandRes_NON_EXTLOAD(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + assert(ISD::isNON_EXTLoad(N) && "This routine is not for extending loads!"); + assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); + + LoadSDNode *LD = cast(N); + MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0)); + SDOperand Chain = LD->getChain(); + SDOperand Ptr = LD->getBasePtr(); + int SVOffset = LD->getSrcValueOffset(); + unsigned Alignment = LD->getAlignment(); + bool isVolatile = LD->isVolatile(); + + assert(NVT.isByteSized() && "Expanded type not byte sized!"); + + Lo = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset, + isVolatile, Alignment); + + // Increment the pointer to the other half. + unsigned IncrementSize = NVT.getSizeInBits() / 8; + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + DAG.getIntPtrConstant(IncrementSize)); + Hi = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset+IncrementSize, + isVolatile, MinAlign(Alignment, IncrementSize)); + + // Build a factor node to remember that this load is independent of the + // other one. + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + + // Handle endianness of the load. + if (TLI.isBigEndian()) + std::swap(Lo, Hi); + + // Modified the chain - switch anything that used the old chain to use + // the new one. + ReplaceValueWith(SDOperand(N, 1), Chain); +} + +//===--------------------------------------------------------------------===// +// Generic Operand Expansion. +//===--------------------------------------------------------------------===// + +SDOperand DAGTypeLegalizer::ExpandOp_BIT_CONVERT(SDNode *N) { + if (N->getValueType(0).isVector()) { + // An illegal expanding type is being converted to a legal vector type. + // Make a two element vector out of the expanded parts and convert that + // instead, but only if the new vector type is legal (otherwise there + // is no point, and it might create expansion loops). For example, on + // x86 this turns v1i64 = BIT_CONVERT i64 into v1i64 = BIT_CONVERT v2i32. + MVT OVT = N->getOperand(0).getValueType(); + MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OVT), 2); + + if (isTypeLegal(NVT)) { + SDOperand Parts[2]; + GetExpandedOp(N->getOperand(0), Parts[0], Parts[1]); + + if (TLI.isBigEndian()) + std::swap(Parts[0], Parts[1]); + + SDOperand Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2); + return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec); + } + } + + // Otherwise, store to a temporary and load out again as the new type. + return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0)); +} + +SDOperand DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) { + // The vector type is legal but the element type needs expansion. + MVT VecVT = N->getValueType(0); + unsigned NumElts = VecVT.getVectorNumElements(); + MVT OldVT = N->getOperand(0).getValueType(); + MVT NewVT = TLI.getTypeToTransformTo(OldVT); + + // Build a vector of twice the length out of the expanded elements. + // For example <3 x i64> -> <6 x i32>. + std::vector NewElts; + NewElts.reserve(NumElts*2); + + for (unsigned i = 0; i < NumElts; ++i) { + SDOperand Lo, Hi; + GetExpandedOp(N->getOperand(i), Lo, Hi); + if (TLI.isBigEndian()) + std::swap(Lo, Hi); + NewElts.push_back(Lo); + NewElts.push_back(Hi); + } + + SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR, + MVT::getVectorVT(NewVT, NewElts.size()), + &NewElts[0], NewElts.size()); + + // Convert the new vector to the old vector type. + return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec); +} + +SDOperand DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) { + SDOperand Lo, Hi; + GetExpandedOp(N->getOperand(0), Lo, Hi); + return cast(N->getOperand(1))->getValue() ? Hi : Lo; +} + +SDOperand DAGTypeLegalizer::ExpandOp_NON_TRUNCStore(SDNode *N, unsigned OpNo) { + assert(ISD::isNON_TRUNCStore(N) && "This routine not for truncating stores!"); + assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); + assert(OpNo == 1 && "Can only expand the stored value so far"); + + StoreSDNode *St = cast(N); + MVT NVT = TLI.getTypeToTransformTo(St->getValue().getValueType()); + SDOperand Chain = St->getChain(); + SDOperand Ptr = St->getBasePtr(); + int SVOffset = St->getSrcValueOffset(); + unsigned Alignment = St->getAlignment(); + bool isVolatile = St->isVolatile(); + + assert(NVT.isByteSized() && "Expanded type not byte sized!"); + unsigned IncrementSize = NVT.getSizeInBits() / 8; + + SDOperand Lo, Hi; + GetExpandedOp(St->getValue(), Lo, Hi); + + if (TLI.isBigEndian()) + std::swap(Lo, Hi); + + Lo = DAG.getStore(Chain, Lo, Ptr, St->getSrcValue(), SVOffset, + isVolatile, Alignment); + + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + DAG.getIntPtrConstant(IncrementSize)); + assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); + Hi = DAG.getStore(Chain, Hi, Ptr, St->getSrcValue(), SVOffset + IncrementSize, + isVolatile, MinAlign(Alignment, IncrementSize)); + + return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); +} + + +//===--------------------------------------------------------------------===// +// Generic Result Splitting. +//===--------------------------------------------------------------------===// + +// Be careful to make no assumptions about which of Lo/Hi is stored first in +// memory (for vectors it is always Lo first followed by Hi in the following +// bytes; for integers and floats it is Lo first if and only if the machine is +// little-endian). + +void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // A MERGE_VALUES node can produce any number of values. We know that the + // first illegal one needs to be expanded into Lo/Hi. + unsigned i; + + // The string of legal results gets turns into the input operands, which have + // the same type. + for (i = 0; isTypeLegal(N->getValueType(i)); ++i) + ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); + + // The first illegal result must be the one that needs to be expanded. + GetSplitOp(N->getOperand(i), Lo, Hi); + + // Legalize the rest of the results into the input operands whether they are + // legal or not. + unsigned e = N->getNumValues(); + for (++i; i != e; ++i) + ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); +} + +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); +} + +void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + SDOperand LL, LH, RL, RH; + GetSplitOp(N->getOperand(2), LL, LH); + GetSplitOp(N->getOperand(3), RL, RH); + + Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), + N->getOperand(1), LL, RL, N->getOperand(4)); + Hi = DAG.getNode(ISD::SELECT_CC, LH.getValueType(), N->getOperand(0), + N->getOperand(1), LH, RH, N->getOperand(4)); +} + +void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) { + MVT LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + Lo = DAG.getNode(ISD::UNDEF, LoVT); + Hi = DAG.getNode(ISD::UNDEF, HiVT); +} diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index b5515116bb0..05c39118219 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -56,8 +56,9 @@ void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { assert(0 && "Do not know how to scalarize the result of this operator!"); abort(); - case ISD::UNDEF: R = ScalarizeRes_UNDEF(N); break; - case ISD::LOAD: R = ScalarizeRes_LOAD(cast(N)); break; + case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break; + case ISD::LOAD: R = ScalarizeVecRes_LOAD(cast(N)); break; + case ISD::ADD: case ISD::FADD: case ISD::SUB: @@ -73,18 +74,20 @@ void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { case ISD::FPOW: case ISD::AND: case ISD::OR: - case ISD::XOR: R = ScalarizeRes_BinOp(N); break; + case ISD::XOR: R = ScalarizeVecRes_BinOp(N); break; + case ISD::FNEG: case ISD::FABS: case ISD::FSQRT: case ISD::FSIN: - case ISD::FCOS: R = ScalarizeRes_UnaryOp(N); break; - case ISD::FPOWI: R = ScalarizeRes_FPOWI(N); break; + case ISD::FCOS: R = ScalarizeVecRes_UnaryOp(N); break; + + case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break; case ISD::BUILD_VECTOR: R = N->getOperand(0); break; - case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break; - case ISD::VECTOR_SHUFFLE: R = ScalarizeRes_VECTOR_SHUFFLE(N); break; - case ISD::BIT_CONVERT: R = ScalarizeRes_BIT_CONVERT(N); break; - case ISD::SELECT: R = ScalarizeRes_SELECT(N); break; + case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break; + case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break; + case ISD::BIT_CONVERT: R = ScalarizeVecRes_BIT_CONVERT(N); break; + case ISD::SELECT: R = ScalarizeVecRes_SELECT(N); break; } // If R is null, the sub-method took care of registering the result. @@ -92,11 +95,11 @@ void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) { SetScalarizedVector(SDOperand(N, ResNo), R); } -SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) { return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType()); } -SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) { // FIXME: Add support for indexed loads. SDOperand Result = DAG.getLoad(N->getValueType(0).getVectorElementType(), N->getChain(), N->getBasePtr(), @@ -109,23 +112,23 @@ SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) { return Result; } -SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) { SDOperand LHS = GetScalarizedVector(N->getOperand(0)); SDOperand RHS = GetScalarizedVector(N->getOperand(1)); return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); } -SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) { SDOperand Op = GetScalarizedVector(N->getOperand(0)); return DAG.getNode(N->getOpcode(), Op.getValueType(), Op); } -SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) { SDOperand Op = GetScalarizedVector(N->getOperand(0)); return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); } -SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) { // The value to insert may have a wider type than the vector element type, // so be sure to truncate it to the element type if necessary. SDOperand Op = N->getOperand(1); @@ -136,19 +139,19 @@ SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) { return Op; } -SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) { // Figure out if the scalar is the LHS or RHS and return it. SDOperand EltNum = N->getOperand(2).getOperand(0); unsigned Op = cast(EltNum)->getValue() != 0; return GetScalarizedVector(N->getOperand(Op)); } -SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) { MVT NewVT = N->getValueType(0).getVectorElementType(); return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0)); } -SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) { SDOperand LHS = GetScalarizedVector(N->getOperand(1)); return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS, GetScalarizedVector(N->getOperand(2))); @@ -182,13 +185,13 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { abort(); case ISD::BIT_CONVERT: - Res = ScalarizeOp_BIT_CONVERT(N); break; + Res = ScalarizeVecOp_BIT_CONVERT(N); break; case ISD::EXTRACT_VECTOR_ELT: - Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break; + Res = ScalarizeVecOp_EXTRACT_VECTOR_ELT(N); break; case ISD::STORE: - Res = ScalarizeOp_STORE(cast(N), OpNo); break; + Res = ScalarizeVecOp_STORE(cast(N), OpNo); break; } } @@ -212,23 +215,23 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) { return false; } -/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector that needs +/// ScalarizeVecOp_BIT_CONVERT - If the value to convert is a vector that needs /// to be scalarized, it must be <1 x ty>. Convert the element instead. -SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecOp_BIT_CONVERT(SDNode *N) { SDOperand Elt = GetScalarizedVector(N->getOperand(0)); return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt); } -/// ScalarizeOp_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 +/// 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. -SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) { +SDOperand DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { return GetScalarizedVector(N->getOperand(0)); } -/// ScalarizeOp_STORE - If the value to store is a vector that needs to be +/// ScalarizeVecOp_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) { +SDOperand DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){ // FIXME: Add support for indexed stores. assert(OpNo == 1 && "Do not know how to scalarize this operand!"); return DAG.getStore(N->getChain(), GetScalarizedVector(N->getOperand(1)), @@ -237,23 +240,6 @@ SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) { } -/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector -/// type that needs to be split. This handles non-power of two vectors. -static void GetSplitDestVTs(MVT InVT, MVT &Lo, MVT &Hi) { - MVT NewEltVT = InVT.getVectorElementType(); - unsigned NumElements = InVT.getVectorNumElements(); - if ((NumElements & (NumElements-1)) == 0) { // Simple power of two vector. - NumElements >>= 1; - Lo = Hi = MVT::getVectorVT(NewEltVT, NumElements); - } else { // Non-power-of-two vectors. - unsigned NewNumElts_Lo = 1 << Log2_32(NumElements); - unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo; - Lo = MVT::getVectorVT(NewEltVT, NewNumElts_Lo); - Hi = MVT::getVectorVT(NewEltVT, NewNumElts_Hi); - } -} - - //===----------------------------------------------------------------------===// // Result Vector Splitting //===----------------------------------------------------------------------===// @@ -290,14 +276,20 @@ 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(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::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; + case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; + case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; + case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; + + case ISD::LOAD: + SplitVecRes_LOAD(cast(N), Lo, Hi); + break; + case ISD::BUILD_PAIR: SplitVecRes_BUILD_PAIR(N, Lo, Hi); break; + case ISD::INSERT_VECTOR_ELT:SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break; + case ISD::VECTOR_SHUFFLE: SplitVecRes_VECTOR_SHUFFLE(N, Lo, Hi); break; + case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break; + case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break; + case ISD::BIT_CONVERT: SplitVecRes_BIT_CONVERT(N, Lo, Hi); break; case ISD::CTTZ: case ISD::CTLZ: case ISD::CTPOP: @@ -309,7 +301,7 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { 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::UINT_TO_FP: SplitVecRes_UnOp(N, Lo, Hi); break; case ISD::ADD: case ISD::SUB: case ISD::MUL: @@ -325,9 +317,8 @@ 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::FPOWI: SplitRes_FPOWI(N, Lo, Hi); break; - case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; + case ISD::FREM: SplitVecRes_BinOp(N, Lo, Hi); break; + case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break; } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -335,16 +326,8 @@ void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) { SetSplitVector(SDOperand(N, ResNo), Lo, Hi); } -void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - MVT LoVT, HiVT; - GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); - - Lo = DAG.getNode(ISD::UNDEF, LoVT); - Hi = DAG.getNode(ISD::UNDEF, HiVT); -} - -void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD, - SDOperand &Lo, SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDOperand &Lo, + SDOperand &Hi) { // FIXME: Add support for indexed loads. MVT LoVT, HiVT; GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT); @@ -374,14 +357,19 @@ void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD, ReplaceValueWith(SDOperand(LD, 1), TF); } -void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_BUILD_PAIR(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { +#ifndef NDEBUG + MVT LoVT, HiVT; + GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + assert(LoVT == HiVT && "Non-power-of-two vectors not supported!"); +#endif Lo = N->getOperand(0); Hi = N->getOperand(1); } -void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { SDOperand Vec = N->getOperand(0); SDOperand Elt = N->getOperand(1); SDOperand Idx = N->getOperand(2); @@ -412,11 +400,11 @@ void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand Load = DAG.getLoad(VecVT, Store, StackPtr, NULL, 0); // Split it. - SplitRes_LOAD(cast(Load.Val), Lo, Hi); + SplitVecRes_LOAD(cast(Load.Val), Lo, Hi); } -void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { // Build the low part. SDOperand Mask = N->getOperand(2); SmallVector Ops; @@ -455,8 +443,8 @@ void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N, Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size()); } -void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { MVT LoVT, HiVT; GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); unsigned LoNumElts = LoVT.getVectorNumElements(); @@ -467,8 +455,8 @@ void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size()); } -void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { // FIXME: Handle non-power-of-two vectors? unsigned NumSubvectors = N->getNumOperands() / 2; if (NumSubvectors == 1) { @@ -487,8 +475,8 @@ void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N, Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size()); } -void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N, - SDOperand &Lo, SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_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. MVT LoVT, HiVT; @@ -512,10 +500,7 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N, // If the vector is being split in two then we can just convert the // expanded pieces. if (LoVT == HiVT) { - if (InVT.isInteger()) - GetExpandedInteger(InOp, Lo, Hi); - else - GetExpandedFloat(InOp, Lo, Hi); + GetExpandedOp(InOp, Lo, Hi); if (TLI.isBigEndian()) std::swap(Lo, Hi); Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo); @@ -546,7 +531,8 @@ void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N, Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi); } -void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { SDOperand LHSLo, LHSHi; GetSplitVector(N->getOperand(0), LHSLo, LHSHi); SDOperand RHSLo, RHSHi; @@ -556,7 +542,8 @@ 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) { +void DAGTypeLegalizer::SplitVecRes_UnOp(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { // Get the dest types. This doesn't always match input types, e.g. int_to_fp. MVT LoVT, HiVT; GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); @@ -566,24 +553,14 @@ void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) { Hi = DAG.getNode(N->getOpcode(), HiVT, Hi); } -void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) { +void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { GetSplitVector(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; - GetSplitVector(N->getOperand(1), LL, LH); - GetSplitVector(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 //===----------------------------------------------------------------------===// @@ -611,14 +588,16 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) { #endif assert(0 && "Do not know how to split this operator's operand!"); abort(); - case ISD::STORE: Res = SplitOp_STORE(cast(N), OpNo); break; - case ISD::RET: Res = SplitOp_RET(N, OpNo); break; + case ISD::STORE: Res = SplitVecOp_STORE(cast(N), OpNo); break; + case ISD::RET: Res = SplitVecOp_RET(N, OpNo); break; - case ISD::BIT_CONVERT: Res = SplitOp_BIT_CONVERT(N); break; + case ISD::BIT_CONVERT: Res = SplitVecOp_BIT_CONVERT(N); break; - case ISD::EXTRACT_VECTOR_ELT: Res = SplitOp_EXTRACT_VECTOR_ELT(N); break; - case ISD::EXTRACT_SUBVECTOR: Res = SplitOp_EXTRACT_SUBVECTOR(N); break; - case ISD::VECTOR_SHUFFLE: Res = SplitOp_VECTOR_SHUFFLE(N, OpNo); break; + case ISD::EXTRACT_VECTOR_ELT: Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break; + case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break; + case ISD::VECTOR_SHUFFLE: + Res = SplitVecOp_VECTOR_SHUFFLE(N, OpNo); + break; } } @@ -642,7 +621,7 @@ bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) { return false; } -SDOperand DAGTypeLegalizer::SplitOp_STORE(StoreSDNode *N, unsigned OpNo) { +SDOperand DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { // FIXME: Add support for indexed stores. assert(OpNo == 1 && "Can only split the stored value"); @@ -667,7 +646,7 @@ SDOperand DAGTypeLegalizer::SplitOp_STORE(StoreSDNode *N, unsigned OpNo) { return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); } -SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) { +SDOperand DAGTypeLegalizer::SplitVecOp_RET(SDNode *N, unsigned OpNo) { assert(N->getNumOperands() == 3 &&"Can only handle ret of one vector so far"); // FIXME: Returns of gcc generic vectors larger than a legal vector // type should be returned by reference! @@ -680,7 +659,7 @@ SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) { return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign); } -SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) { +SDOperand 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 // split pieces into integers and reassemble. @@ -696,7 +675,7 @@ SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) { JoinIntegers(Lo, Hi)); } -SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) { +SDOperand DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { SDOperand Vec = N->getOperand(0); SDOperand Idx = N->getOperand(1); MVT VecVT = Vec.getValueType(); @@ -728,7 +707,7 @@ SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) { return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0); } -SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) { +SDOperand DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) { // We know that the extracted result type is legal. For now, assume the index // is a constant. MVT SubVT = N->getValueType(0); @@ -749,7 +728,7 @@ SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) { } } -SDOperand DAGTypeLegalizer::SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) { +SDOperand DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo){ assert(OpNo == 2 && "Shuffle source type differs from result type?"); SDOperand Mask = N->getOperand(2); unsigned MaskLength = Mask.getValueType().getVectorNumElements();