aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
diff options
context:
space:
mode:
authorFraser Cormack <fraser@codeplay.com>2021-05-07 15:25:40 +0100
committerFraser Cormack <fraser@codeplay.com>2021-05-12 16:33:07 +0100
commitc5ec00e62b0e7b91eb07e25441c7ed38227f5bf3 (patch)
tree9c9b67607faf2fb88e62cecd622a87bc23b7c905 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
parent6110b667b0537104ee139a5c6efc726f902db4de (diff)
downloadllvm-c5ec00e62b0e7b91eb07e25441c7ed38227f5bf3.zip
llvm-c5ec00e62b0e7b91eb07e25441c7ed38227f5bf3.tar.gz
llvm-c5ec00e62b0e7b91eb07e25441c7ed38227f5bf3.tar.bz2
[TargetLowering] Improve legalization of scalable vector types
This patch extends the vector type-conversion and legalization capabilities of scalable vector types. Firstly, `vscale x 1` types now behave more like the corresponding `vscale x 2+` types. This enables the integer promotion legalization of extended scalable types, such as the promotion of `<vscale x 1 x i5>` to `<vscale x 1 x i8>`. These `vscale x 1` types are also now better handled by `getVectorTypeBreakdown`, where what looks like older handling for 1-element fixed-length vector types was spuriously updated to include scalable types. Widening of scalable types is now better supported, by using `INSERT_SUBVECTOR` to insert the smaller scalable vector "value" type into the wider scalable vector "part" type. This allows AArch64 to pass and return `vscale x 1` types by value by widening. There are still cases where we are unable to legalize `vscale x 1` types, such as where expansion would require splitting the vector in two. Reviewed By: sdesmalen Differential Revision: https://reviews.llvm.org/D102073
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp49
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