[llvm] [SLP][REVEC] Make SLP vectorize shufflevector. (PR #102489)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 9 04:40:36 PDT 2024
================
@@ -268,6 +268,98 @@ static void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements,
Mask.swap(NewMask);
}
+/// \returns the number of groups of shufflevector
+/// A group has the following features
+/// 1. All of value in a group are shufflevector.
+/// 2. The mask of all shufflevector is isExtractSubvectorMask.
+/// 3. The mask of all shufflevector uses all of the elements of the source (and
+/// the elements are used in order).
+/// e.g., it is 1 group (%0)
+/// %1 = shufflevector <16 x i8> %0, <16 x i8> poison,
+/// <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
+/// %2 = shufflevector <16 x i8> %0, <16 x i8> poison,
+/// <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+/// it is 2 groups (%3 and %4)
+/// %5 = shufflevector <8 x i16> %3, <8 x i16> poison,
+/// <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+/// %6 = shufflevector <8 x i16> %3, <8 x i16> poison,
+/// <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+/// %7 = shufflevector <8 x i16> %4, <8 x i16> poison,
+/// <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+/// %8 = shufflevector <8 x i16> %4, <8 x i16> poison,
+/// <4 x i32> <i32 4, i32 5, i32 6, i32 7>
+/// it is 0 group
+/// %12 = shufflevector <8 x i16> %10, <8 x i16> poison,
+/// <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+/// %13 = shufflevector <8 x i16> %11, <8 x i16> poison,
+/// <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+static unsigned getShufflevectorNumGroups(ArrayRef<Value *> VL) {
+ if (VL.empty())
+ return 0;
+ if (!all_of(VL, IsaPred<ShuffleVectorInst>))
+ return 0;
+ auto *SV = cast<ShuffleVectorInst>(VL.front());
+ unsigned SVNumElements =
+ cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
+ unsigned GroupSize = SVNumElements / SV->getShuffleMask().size();
+ if (GroupSize == 0 || (VL.size() % GroupSize) != 0)
+ return 0;
+ unsigned NumGroup = 0;
+ for (size_t I = 0, E = VL.size(); I != E; I += GroupSize) {
+ auto *SV = cast<ShuffleVectorInst>(VL[I]);
+ Value *Src = SV->getOperand(0);
+ ArrayRef<Value *> Group = VL.slice(I, GroupSize);
+ SmallVector<int> ExtractionIndex(SVNumElements);
+ if (!all_of(Group, [&](Value *V) {
+ auto *SV = cast<ShuffleVectorInst>(V);
+ // From the same source.
+ if (SV->getOperand(0) != Src)
+ return false;
+ int Index;
+ if (!SV->isExtractSubvectorMask(Index))
+ return false;
+ for (int I : seq<int>(Index, Index + SV->getShuffleMask().size()))
+ ExtractionIndex.push_back(I);
+ return true;
+ }))
+ return 0;
+ if (!std::is_sorted(ExtractionIndex.begin(), ExtractionIndex.end()))
----------------
alexey-bataev wrote:
`!is_sorted(ExtractionIndex)`
https://github.com/llvm/llvm-project/pull/102489
More information about the llvm-commits
mailing list