[llvm] [SandboxVec] Add a simple pack reuse pass (PR #141848)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 3 09:29:33 PDT 2025


================
@@ -179,13 +197,61 @@ class VecUtils {
   /// \Returns the first integer power of 2 that is <= Num.
   static unsigned getFloorPowerOf2(unsigned Num);
 
+  /// If \p I is the last instruction of a pack pattern, then this function
+  /// returns the instructions in the pack and the operands in the pack, else
+  /// returns nullopt.
+  static std::optional<
+      std::pair<SmallVector<Instruction *>, SmallVector<Value *>>>
+  matchPack(Instruction *I) {
+    // TODO: Support vector pack patterns.
+    // TODO: Support out-of-order inserts.
+
+    // Early return if `I` is not an Insert.
+    if (!isa<InsertElementInst>(I))
+      return std::nullopt;
+    auto *BB0 = I->getParent();
+    // The pack contains as many instrs as the lanes of the bottom-most Insert
+    unsigned ExpectedNumInserts = VecUtils::getNumLanes(I);
+    assert(ExpectedNumInserts >= 2 && "Expected at least 2 inserts!");
+    SmallVector<Instruction *> PackInstrs;
+    SmallVector<Value *> PackOperands;
+    PackOperands.resize(ExpectedNumInserts);
+    // Collect the inserts by walking up the use-def chain.
+    Instruction *InsertI = I;
+    for ([[maybe_unused]] auto Cnt : seq<unsigned>(ExpectedNumInserts)) {
+      if (InsertI == nullptr)
+        return std::nullopt;
+      if (InsertI->getParent() != BB0)
+        return std::nullopt;
+      // Check the lane.
+      auto *LaneC = dyn_cast<ConstantInt>(InsertI->getOperand(2));
+      unsigned ExpectedLane = ExpectedNumInserts - Cnt - 1;
+      if (LaneC == nullptr || LaneC->getSExtValue() != ExpectedLane)
+        return std::nullopt;
+      PackInstrs.push_back(InsertI);
+      PackOperands[ExpectedLane] = InsertI->getOperand(1);
+
+      Value *Op = InsertI->getOperand(0);
+      if (Cnt == ExpectedNumInserts - 1) {
+        if (!isa<PoisonValue>(Op))
+          return std::nullopt;
+      } else {
+        InsertI = dyn_cast<InsertElementInst>(Op);
+      }
+    }
+    // Check the topmost insert. The operand should be a Poison.
----------------
vporpo wrote:

Yes, fixed.

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


More information about the llvm-commits mailing list