[llvm] [Instructions] cache computed shufflevector properties (PR #115536)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 17 05:47:32 PST 2024
================
@@ -1844,6 +1852,106 @@ Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask,
return ConstantVector::get(MaskConst);
}
+ShuffleMaskAttrs ShuffleVectorInst::analyzeMask(ArrayRef<int> Mask,
+ int NumOpElts, bool Scalable,
+ bool HasUndefOp) {
+ assert(!Mask.empty() && "Shuffle mask must contain elements");
+
+ using SizeTy = decltype(Mask.size());
+ bool UsesLHS = false;
+ bool UsesRHS = false;
+ bool ExtendsWithPadding = Mask.size() > static_cast<SizeTy>(NumOpElts);
+ const bool Extracts = Mask.size() < static_cast<SizeTy>(NumOpElts);
+ const bool PreservesLength = Mask.size() == static_cast<SizeTy>(NumOpElts);
+ bool CrossesLanes = false;
+ bool ReversesLanes = NumOpElts >= 2;
+ bool FirstLaneOnly = true;
+ bool HasTransposeInterleaving = true;
+ std::optional<int> SpliceIndex;
+ bool Splices = true;
+
+ for (int Idx = 0, NumMaskElts = Mask.size(); Idx < NumMaskElts; ++Idx) {
+ const auto I = Mask[Idx];
+ if (I == -1) {
+ HasTransposeInterleaving = false;
+ continue;
+ }
+ assert(I >= 0 && I < (NumOpElts * 2) &&
+ "Out-of-bounds shuffle mask element");
+ UsesLHS |= (I < NumOpElts);
+ UsesRHS |= (I >= NumOpElts);
+ CrossesLanes |= I != Idx && I != (NumOpElts + Idx);
+ ReversesLanes &=
+ I == (NumOpElts - 1 - Idx) || I == (NumOpElts + NumOpElts - 1 - Idx);
+ FirstLaneOnly &= I == 0 || I == NumOpElts;
+
+ if (Idx >= 2)
+ HasTransposeInterleaving &= Mask[Idx] - Mask[Idx - 2] == 2;
+ else if (Idx == 1)
+ HasTransposeInterleaving &= Mask[Idx] - Mask[0] == NumOpElts;
+ else // Idx == 0
+ HasTransposeInterleaving &= I == 0 || I == 1;
+
+ if (!SpliceIndex) {
+ Splices &= I >= Idx && I - Idx < NumOpElts;
+ if (Splices)
+ SpliceIndex = I - Idx;
+ } else {
+ Splices &= I == *SpliceIndex + Idx;
+ }
+
+ // Padding occurs when the mask size is >= operand size (see above) and all
+ // remaining elements must be undef.
+ ExtendsWithPadding &= Idx < NumOpElts;
+ }
+
+ ShuffleMaskAttrs MaskAttrs = {};
+
+ // Single-source if uses either LHS or RHS but not both.
+ MaskAttrs.SingleSource = (UsesLHS ^ UsesRHS) && PreservesLength;
----------------
RKSimon wrote:
How much of penalty do we see if we just use:
```
MaskAttrs.SingleSource = !changesLength() && isSingleSourceMask(Mask, Mask.size())
```
etc. for all the other kinds - I don't want to find myself pulling my hair out finding subtle diffs between all of this and the individual static matchers.
https://github.com/llvm/llvm-project/pull/115536
More information about the llvm-commits
mailing list