aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorKevin Athey <kda@google.com>2022-12-15 11:19:24 -0800
committerKevin Athey <kda@google.com>2022-12-15 11:19:24 -0800
commitec7cffc579737d086addf22bb155e76e5cd30ab3 (patch)
tree44f3b1bd71d2d5268010f3946fb9c484678cdcc1 /llvm/lib
parent192cc76e0be688106492989cd845ba786a7ae36d (diff)
downloadllvm-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.cpp74
-rw-r--r--llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp7
-rw-r--r--llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.h1
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,