diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index a8db972..4b2d811 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -607,30 +607,39 @@ static void getCopyToParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, std::reverse(Parts, Parts + OrigNumParts); } -static SDValue widenVectorToPartType(SelectionDAG &DAG, - SDValue Val, const SDLoc &DL, EVT PartVT) { - if (!PartVT.isFixedLengthVector()) +static SDValue widenVectorToPartType(SelectionDAG &DAG, SDValue Val, + const SDLoc &DL, EVT PartVT) { + if (!PartVT.isVector()) return SDValue(); EVT ValueVT = Val.getValueType(); - unsigned PartNumElts = PartVT.getVectorNumElements(); - unsigned ValueNumElts = ValueVT.getVectorNumElements(); - if (PartNumElts > ValueNumElts && - PartVT.getVectorElementType() == ValueVT.getVectorElementType()) { - EVT ElementVT = PartVT.getVectorElementType(); - // Vector widening case, e.g. <2 x float> -> <4 x float>. Shuffle in - // undef elements. - SmallVector<SDValue, 16> Ops; - DAG.ExtractVectorElements(Val, Ops); - SDValue EltUndef = DAG.getUNDEF(ElementVT); - for (unsigned i = ValueNumElts, e = PartNumElts; i != e; ++i) - Ops.push_back(EltUndef); - - // FIXME: Use CONCAT for 2x -> 4x. - return DAG.getBuildVector(PartVT, DL, Ops); - } + ElementCount PartNumElts = PartVT.getVectorElementCount(); + ElementCount ValueNumElts = ValueVT.getVectorElementCount(); + + // We only support widening vectors with equivalent element types and + // fixed/scalable properties. If a target needs to widen a fixed-length type + // to a scalable one, it should be possible to use INSERT_SUBVECTOR below. + if (ElementCount::isKnownLE(PartNumElts, ValueNumElts) || + PartNumElts.isScalable() != ValueNumElts.isScalable() || + PartVT.getVectorElementType() != ValueVT.getVectorElementType()) + return SDValue(); - return SDValue(); + // Widening a scalable vector to another scalable vector is done by inserting + // the vector into a larger undef one. + if (PartNumElts.isScalable()) + return DAG.getNode(ISD::INSERT_SUBVECTOR, DL, PartVT, DAG.getUNDEF(PartVT), + Val, DAG.getVectorIdxConstant(0, DL)); + + EVT ElementVT = PartVT.getVectorElementType(); + // Vector widening case, e.g. <2 x float> -> <4 x float>. Shuffle in + // undef elements. + SmallVector<SDValue, 16> Ops; + DAG.ExtractVectorElements(Val, Ops); + SDValue EltUndef = DAG.getUNDEF(ElementVT); + Ops.append((PartNumElts - ValueNumElts).getFixedValue(), EltUndef); + + // FIXME: Use CONCAT for 2x -> 4x. + return DAG.getBuildVector(PartVT, DL, Ops); } /// getCopyToPartsVector - Create a series of nodes that contain the specified |