[llvm] [LSV] Support vectorization of mixed-type contiguous accesses (PR #177908)
Drew Kersnar via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 4 10:50:30 PST 2026
================
@@ -1114,6 +1175,46 @@ bool Vectorizer::vectorizeChain(Chain &C) {
}
assert(8 * ChainBytes % DL.getTypeSizeInBits(VecElemTy) == 0);
+
+ // Validate that we can legally cast the extracted elements to the original
+ // types. This is critical for pointer types where we can't cast vectors to
+ // pointers.
+ for (const ChainElem &E : C) {
+ Type *OriginalTy = getLoadStoreType(E.Inst);
+ Type *OriginalScalarTy = OriginalTy->getScalarType();
+ unsigned OriginalSize = DL.getTypeSizeInBits(OriginalScalarTy);
+ unsigned NumElems = OriginalSize / VecElemSize;
+
+ // Check if the cast from VecElemTy (or vector of it) to OriginalTy would be
+ // valid. For loads, we extract elements and cast them. For stores, we cast
+ // values to VecElemTy.
+ if (IsLoadChain) {
+ Type *ExtractedTy = (NumElems == 1)
+ ? VecElemTy
+ : FixedVectorType::get(VecElemTy, NumElems);
+ // We can cast integer to pointer via inttoptr, but only scalars.
+ // We can bitcast between same-sized types.
+ // We can't cast vectors to pointers.
+ if (OriginalScalarTy->isPointerTy()) {
+ // Verify sizes match for inttoptr cast
+ if (DL.getTypeSizeInBits(ExtractedTy) !=
+ DL.getTypeSizeInBits(OriginalScalarTy)) {
+ {
+ dbgs() << "LSV: Cannot vectorize chain: size mismatch for inttoptr "
+ "cast from "
+ << *ExtractedTy << " to " << *OriginalScalarTy << "\n";
+ };
+ return false;
----------------
dakersnar wrote:
> for (auto &C : splitChainByPtrNonPtrTypes(C))
I agree with @cmc-rep's suggestion, except it will be slightly more complicated than what this name implies, as we still want to vectorize {ptr, i32} together. So the function should really be splitting chains that contain pointers into two groups: 1) chains with pointers and other types that are the same size as the pointers, and 2) "the rest". The heuristic could be made even smarter if we want, deciding whether to keep the non-pointers in the chain with the pointers or moving them to "the rest" if they are more likely to be vectorized with the latter, but my gut says that might be unnecessary.
I also think this could happen after splitChainByMayAliasInstructions if we end up with a more complicated heuristic that would benefit from that filter step happening first to have access to more complete information.
Question: is all of this needed purely because vectors of, say, <2 x i16> cannot be cast to ptr? Can we cast to an i32 as an intermediate step and then cast to the ptr? I'm not familiar with these restrictions so some clarification here would be nice.
https://github.com/llvm/llvm-project/pull/177908
More information about the llvm-commits
mailing list