diff options
| author | Kevin Athey <kda@google.com> | 2022-12-15 11:19:24 -0800 |
|---|---|---|
| committer | Kevin Athey <kda@google.com> | 2022-12-15 11:19:24 -0800 |
| commit | ec7cffc579737d086addf22bb155e76e5cd30ab3 (patch) | |
| tree | 44f3b1bd71d2d5268010f3946fb9c484678cdcc1 /llvm/lib | |
| parent | 192cc76e0be688106492989cd845ba786a7ae36d (diff) | |
| download | llvm-ec7cffc579737d086addf22bb155e76e5cd30ab3.zip llvm-ec7cffc579737d086addf22bb155e76e5cd30ab3.tar.gz llvm-ec7cffc579737d086addf22bb155e76e5cd30ab3.tar.bz2 | |
Revert "Revert "[AArch64][GlobalISel][Legalizer] Legalize G_SHUFFLE_VECTOR with different lengths""
This reverts commit 192cc76e0be688106492989cd845ba786a7ae36d.
Reverted Revert, as build was fixed while I was examining.
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 74 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h | 1 |
3 files changed, 79 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index bd9c156..dd5851f 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -4944,12 +4944,72 @@ LegalizerHelper::moreElementsVector(MachineInstr &MI, unsigned TypeIdx, } } +/// Expand source vectors to the size of destination vector. +static LegalizerHelper::LegalizeResult +equalizeVectorShuffleLengths(MachineInstr &MI, MachineIRBuilder &MIRBuilder) { + MachineRegisterInfo &MRI = *MIRBuilder.getMRI(); + + LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); + LLT SrcTy = MRI.getType(MI.getOperand(1).getReg()); + ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask(); + unsigned MaskNumElts = Mask.size(); + unsigned SrcNumElts = SrcTy.getNumElements(); + Register DstReg = MI.getOperand(0).getReg(); + LLT DestEltTy = DstTy.getElementType(); + + // TODO: Normalize the shuffle vector since mask and vector length don't + // match. + if (MaskNumElts <= SrcNumElts) { + return LegalizerHelper::LegalizeResult::UnableToLegalize; + } + + unsigned PaddedMaskNumElts = alignTo(MaskNumElts, SrcNumElts); + unsigned NumConcat = PaddedMaskNumElts / SrcNumElts; + LLT PaddedTy = LLT::fixed_vector(PaddedMaskNumElts, DestEltTy); + + // Create new source vectors by concatenating the initial + // source vectors with undefined vectors of the same size. + auto Undef = MIRBuilder.buildUndef(SrcTy); + SmallVector<Register, 8> MOps1(NumConcat, Undef.getReg(0)); + SmallVector<Register, 8> MOps2(NumConcat, Undef.getReg(0)); + MOps1[0] = MI.getOperand(1).getReg(); + MOps2[0] = MI.getOperand(2).getReg(); + + auto Src1 = MIRBuilder.buildConcatVectors(PaddedTy, MOps1); + auto Src2 = MIRBuilder.buildConcatVectors(PaddedTy, MOps2); + + // Readjust mask for new input vector length. + SmallVector<int, 8> MappedOps(PaddedMaskNumElts, -1); + for (unsigned I = 0; I != MaskNumElts; ++I) { + int Idx = Mask[I]; + if (Idx >= static_cast<int>(SrcNumElts)) + Idx += PaddedMaskNumElts - SrcNumElts; + MappedOps[I] = Idx; + } + + // If we got more elements than required, extract subvector. + if (MaskNumElts != PaddedMaskNumElts) { + auto Shuffle = + MIRBuilder.buildShuffleVector(PaddedTy, Src1, Src2, MappedOps); + + SmallVector<Register, 16> Elts(MaskNumElts); + for (unsigned I = 0; I < MaskNumElts; ++I) { + Elts[I] = + MIRBuilder.buildExtractVectorElementConstant(DestEltTy, Shuffle, I) + .getReg(0); + } + MIRBuilder.buildBuildVector(DstReg, Elts); + } else { + MIRBuilder.buildShuffleVector(DstReg, Src1, Src2, MappedOps); + } + + MI.eraseFromParent(); + return LegalizerHelper::LegalizeResult::Legalized; +} + LegalizerHelper::LegalizeResult LegalizerHelper::moreElementsVectorShuffle(MachineInstr &MI, unsigned int TypeIdx, LLT MoreTy) { - if (TypeIdx != 0) - return UnableToLegalize; - Register DstReg = MI.getOperand(0).getReg(); Register Src1Reg = MI.getOperand(1).getReg(); Register Src2Reg = MI.getOperand(2).getReg(); @@ -4960,6 +5020,14 @@ LegalizerHelper::moreElementsVectorShuffle(MachineInstr &MI, unsigned NumElts = DstTy.getNumElements(); unsigned WidenNumElts = MoreTy.getNumElements(); + if (DstTy.isVector() && Src1Ty.isVector() && + DstTy.getNumElements() > Src1Ty.getNumElements()) { + return equalizeVectorShuffleLengths(MI, MIRBuilder); + } + + if (TypeIdx != 0) + return UnableToLegalize; + // Expect a canonicalized shuffle. if (DstTy != Src1Ty || DstTy != Src2Ty) return UnableToLegalize; diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp index d267936..48d6553 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp @@ -686,6 +686,13 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) .lowerIf([=](const LegalityQuery &Query) { return !Query.Types[1].isVector(); }) + .moreElementsIf( + [](const LegalityQuery &Query) { + return Query.Types[0].isVector() && Query.Types[1].isVector() && + Query.Types[0].getNumElements() > + Query.Types[1].getNumElements(); + }, + changeTo(1, 0)) .moreElementsToNextPow2(0) .clampNumElements(0, v4s32, v4s32) .clampNumElements(0, v2s64, v2s64); diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h index c10f6e0..2a13a36 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h +++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h @@ -47,6 +47,7 @@ private: MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const; bool legalizeVectorTrunc(MachineInstr &MI, LegalizerHelper &Helper) const; + bool legalizeShuffleVector(MachineInstr &MI, LegalizerHelper &Helper) const; bool legalizeBitfieldExtract(MachineInstr &MI, MachineRegisterInfo &MRI, LegalizerHelper &Helper) const; bool legalizeRotate(MachineInstr &MI, MachineRegisterInfo &MRI, |
