[llvm] Reapply "[X86] EltsFromConsecutiveLoads - handle trunc(wideload()) patterns" (#199371) (PR #208999)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 13 00:07:16 PDT 2026
================
@@ -8065,6 +8065,130 @@ static SDValue EltsFromConsecutiveLoads(EVT VT, ArrayRef<SDValue> Elts,
}
}
+ // STRIDED - element loads at a uniform byte stride larger than the element
+ // size are folded into wide load(s) + vector truncation.
+ // Depth 1 lets the REVERSE block below recurse into us to catch reverse
+ // strides.
+ if (Depth <= 1 && Subtarget.hasAVX2() && !IsConsecutiveLoad &&
+ LoadMask.isAllOnes() && isPowerOf2_32(NumElems) && BaseSizeInBits <= 32 &&
+ VT.getSizeInBits() >= 128) {
+ unsigned WideEltBits = 0;
+ for (unsigned Trial : {16u, 32u, 64u}) {
+ if (Trial <= BaseSizeInBits || Trial % BaseSizeInBits != 0)
+ continue;
+ unsigned LaneStride = Trial / BaseSizeInBits;
+ bool AllMatch = true;
+ for (unsigned K = 1; K < NumElems && AllMatch; ++K) {
+ AllMatch = AllMatch && ByteOffsets[K] == 0 &&
+ DAG.areNonVolatileConsecutiveLoads(
+ Loads[K], LDBase, BaseSizeInBytes, K * LaneStride);
+ }
+ if (AllMatch) {
+ WideEltBits = Trial;
+ break;
+ }
+ }
+ if (WideEltBits != 0) {
+ MVT WideEltVT = MVT::getIntegerVT(WideEltBits);
+ MVT SrcEltVT = MVT::getIntegerVT(BaseSizeInBits);
+ // VTRUNC writes the truncated values to the low lanes of an xmm with
+ // zero padding above.
+ MVT TruncDstVT = MVT::getVectorVT(SrcEltVT, 128 / BaseSizeInBits);
+ unsigned TruncDstLanes = TruncDstVT.getVectorNumElements();
+ MVT ConcatVT = MVT::getVectorVT(SrcEltVT, NumElems);
+ if (NumElems > TruncDstLanes && !TLI.isTypeLegal(ConcatVT))
+ return SDValue();
+ // The wide loads read (stride - element) bytes past the last element.
+ // That is safe if the whole span is dereferenceable or the base is a
+ // fixed stack slot which always has the caller's frame mapped above it.
+ bool RangeSafe = isa_and_nonnull<FixedStackPseudoSourceValue>(
+ LDBase->getMemOperand()->getPseudoValue()) ||
----------------
nikic wrote:
This looks very iffy, is there precedent for this?
For motivating use cases, do you know that the pointer is aligned to the stride? That would be sufficient to show that the page boundary is not crossed.
https://github.com/llvm/llvm-project/pull/208999
More information about the llvm-commits
mailing list