[llvm] [LoadStoreVectorizer] Support vectorization of mixed-type contiguous accesses (PR #177908)

Anshil Gandhi via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 1 08:06:31 PDT 2026


================
@@ -1075,6 +1107,127 @@ std::vector<Chain> Vectorizer::splitChainByAlignment(Chain &C) {
   return Ret;
 }
 
+std::vector<Chain> Vectorizer::splitChainByPointerWidth(Chain &C) {
+  if (C.empty())
+    return {};
+
+  sortChainInOffsetOrder(C);
+
+  LLVM_DEBUG({
+    dbgs() << "LSV: splitChainByPointerWidth considering chain:\n";
+    dumpChain(C);
+  });
+
+  unsigned GCDSize = 0;
+  for (const ChainElem &E : C) {
+    Type *Ty = getLoadStoreType(E.Inst)->getScalarType();
+    unsigned Sz = DL.getTypeSizeInBits(Ty);
+    GCDSize = GCDSize == 0 ? Sz : std::gcd(GCDSize, Sz);
+  }
+
+  Chain MainChain;
+  DenseMap<unsigned, Chain> PtrGroups;
+
+  for (ChainElem &E : C) {
+    Type *ScalarTy = getLoadStoreType(E.Inst)->getScalarType();
+    unsigned Sz = DL.getTypeSizeInBits(ScalarTy);
+    if (ScalarTy->isPointerTy() && Sz > GCDSize) {
+      PtrGroups[Sz].push_back(E);
+    } else {
+      MainChain.push_back(E);
+    }
+  }
+
+  std::vector<Chain> Ret;
+  if (MainChain.size() > 1)
+    Ret.push_back(std::move(MainChain));
+  for (auto &[Size, Group] : PtrGroups) {
+    if (Group.size() > 1)
+      Ret.push_back(std::move(Group));
+  }
+
+  LLVM_DEBUG({
+    dbgs() << "LSV: splitChainByPointerWidth produced " << Ret.size()
+           << " chains\n";
+    for (const auto &Chain : Ret) {
+      dbgs() << "  Chain:\n";
+      dumpChain(Chain);
+    }
+  });
+
+  return Ret;
+}
+
+/// Insert a cast from V's type to NewTy, preserving the underlying bit pattern.
+///
+/// This is used during vectorization to convert between the original types of
+/// chain elements and the vectorized element type (VecElemTy). For example,
+/// when vectorizing a chain of [i32, ptr addrspace(3), float], the vectorized
+/// type might be <3 x i32>, so each element must be cast to/from i32.
+///
+/// The function handles two cases:
+///
+/// 1. Mismatched bitwidths (e.g., i16 value into an i32 vector slot):
+///    Convert the source to a scalar integer of its original width, then
+///    zero-extend or truncate to the target width. Finally, cast to the
+///    destination type via CreateBitPreservingCastChain.
----------------
gandhi56 wrote:

Yup, you are right. After normalization to match bitwidths, `CreateBitOrPointerCast` is sufficient to generate the bitcast instructions.

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


More information about the llvm-commits mailing list