aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TargetLoweringBase.cpp
diff options
context:
space:
mode:
authorSander de Smalen <sander.desmalen@arm.com>2020-06-05 18:29:43 +0100
committerSander de Smalen <sander.desmalen@arm.com>2020-06-08 10:39:18 +0100
commitae09670ee4de461669fc9f09b146ba0a5f0935fb (patch)
tree0a1b4cc87961aece7f68e6107d1739ef50c84cae /llvm/lib/CodeGen/TargetLoweringBase.cpp
parent970bb4a291c0a823786efee7d572a699569ec339 (diff)
downloadllvm-ae09670ee4de461669fc9f09b146ba0a5f0935fb.zip
llvm-ae09670ee4de461669fc9f09b146ba0a5f0935fb.tar.gz
llvm-ae09670ee4de461669fc9f09b146ba0a5f0935fb.tar.bz2
[CodeGen][SVE] CopyToReg: Split scalable EVTs that are not powers of 2
Scalable vectors cannot use 'BUILD_VECTOR', so it is necessary to properly split and widen scalable vectors when passing them to CopyToReg/CopyFromReg. This functionality is added to TargetLoweringBase::getVectorTypeBreakdown(). This patch only adds support for 'splitting' scalable vectors that are a multiple of some legal type, e.g. <vscale x 6 x i64> -> 3 x <vscale x 2 x i64> Reviewers: efriedma, c-rhodes Reviewed By: efriedma Tags: #llvm Differential Revision: https://reviews.llvm.org/D80139
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringBase.cpp')
-rw-r--r--llvm/lib/CodeGen/TargetLoweringBase.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index acc2dce..6ec6498 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -955,6 +955,12 @@ static unsigned getVectorTypeBreakdownMVT(MVT VT, MVT &IntermediateVT,
unsigned NumVectorRegs = 1;
+ // Scalable vectors cannot be scalarized, so splitting or widening is
+ // required.
+ if (VT.isScalableVector() && !isPowerOf2_32(EC.Min))
+ llvm_unreachable(
+ "Splitting or widening of non-power-of-2 MVTs is not implemented.");
+
// FIXME: We don't support non-power-of-2-sized vectors for now.
// Ideally we could break down into LHS/RHS like LegalizeDAG does.
if (!isPowerOf2_32(EC.Min)) {
@@ -1418,8 +1424,34 @@ unsigned TargetLoweringBase::getVectorTypeBreakdown(LLVMContext &Context, EVT VT
unsigned NumVectorRegs = 1;
- // FIXME: We don't support non-power-of-2-sized vectors for now. Ideally we
- // could break down into LHS/RHS like LegalizeDAG does.
+ // Scalable vectors cannot be scalarized, so handle the legalisation of the
+ // types like done elsewhere in SelectionDAG.
+ if (VT.isScalableVector() && !isPowerOf2_32(EltCnt.Min)) {
+ LegalizeKind LK;
+ EVT PartVT = VT;
+ do {
+ // Iterate until we've found a legal (part) type to hold VT.
+ LK = getTypeConversion(Context, PartVT);
+ PartVT = LK.second;
+ } while (LK.first != TypeLegal);
+
+ NumIntermediates =
+ VT.getVectorElementCount().Min / PartVT.getVectorElementCount().Min;
+
+ // FIXME: This code needs to be extended to handle more complex vector
+ // breakdowns, like nxv7i64 -> nxv8i64 -> 4 x nxv2i64. Currently the only
+ // supported cases are vectors that are broken down into equal parts
+ // such as nxv6i64 -> 3 x nxv2i64.
+ assert(NumIntermediates * PartVT.getVectorElementCount().Min ==
+ VT.getVectorElementCount().Min &&
+ "Expected an integer multiple of PartVT");
+ IntermediateVT = PartVT;
+ RegisterVT = getRegisterType(Context, IntermediateVT);
+ return NumIntermediates;
+ }
+
+ // FIXME: We don't support non-power-of-2-sized vectors for now. Ideally
+ // we could break down into LHS/RHS like LegalizeDAG does.
if (!isPowerOf2_32(EltCnt.Min)) {
NumVectorRegs = EltCnt.Min;
EltCnt.Min = 1;