[llvm] [SLP] Split blocking build-vector stores in scalar chains (PR #194970)

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Fri May 1 22:03:03 PDT 2026


================
@@ -26634,6 +26499,53 @@ SLPVectorizerPass::vectorizeStoreChain(ArrayRef<Value *> Chain, BoUpSLP &R,
 }
 
 namespace {
+/// A store-chain element after breaking stores into scalar lanes.
+///
+/// A scalar store contributes one lane. A simple build-vector store contributes
+/// one lane per inserted element, so a store of <a, b, c, d> to p[3] is modeled
+/// as lanes p[3] = a, p[4] = b, p[5] = c, p[6] = d.
+struct StoreLane {
+  StoreInst *Store = nullptr;
+  Value *ScalarValue = nullptr;
+  int64_t Offset = 0;
+  unsigned Lane = 0;
+  bool IsVectorLane = false;
+
+  Align getAlignment(TypeSize EltSize) const {
+    uint64_t StoreOffset = IsVectorLane ? Lane : 0;
+    return commonAlignment(Store->getAlign(),
+                           StoreOffset * EltSize.getFixedValue());
+  }
+};
+
+static bool collectBuildVector(Value *V, SmallVectorImpl<Value *> &Elts,
+                               SmallVectorImpl<Instruction *> &Insts) {
+  auto *VecTy = dyn_cast<FixedVectorType>(V->getType());
+  if (!VecTy)
+    return false;
+  Elts.assign(VecTy->getNumElements(), nullptr);
+  Value *Cur = V;
+  while (auto *IE = dyn_cast<InsertElementInst>(Cur)) {
+    auto *Idx = dyn_cast<ConstantInt>(IE->getOperand(2));
+    if (!Idx || Idx->getValue().uge(Elts.size()))
+      return false;
+    Elts[Idx->getZExtValue()] = IE->getOperand(1);
+    Insts.push_back(IE);
+    Cur = IE->getOperand(0);
+  }
----------------
alexey-bataev wrote:

May cause a compiler crash, need to check for multi-used insertelements, which are the roots of the new buildvector sequence

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


More information about the llvm-commits mailing list