diff options
author | Sander de Smalen <sander.desmalen@arm.com> | 2020-06-05 18:29:43 +0100 |
---|---|---|
committer | Sander de Smalen <sander.desmalen@arm.com> | 2020-06-08 10:39:18 +0100 |
commit | ae09670ee4de461669fc9f09b146ba0a5f0935fb (patch) | |
tree | 0a1b4cc87961aece7f68e6107d1739ef50c84cae /llvm/lib/CodeGen/TargetLoweringBase.cpp | |
parent | 970bb4a291c0a823786efee7d572a699569ec339 (diff) | |
download | llvm-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.cpp | 36 |
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; |