[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