[llvm] [Instructions] cache computed shufflevector properties (PR #115536)

Princeton Ferro via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 17 10:59:13 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;
----------------
Prince781 wrote:

Sorry, I posted that comment without reading your reply. I'll try it with the static matchers then.

https://github.com/llvm/llvm-project/pull/115536


More information about the llvm-commits mailing list