[llvm] Reapply "[X86] EltsFromConsecutiveLoads - handle trunc(wideload()) patterns" (#199371) (PR #208999)

Adam Scott via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 15 21:12:44 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()) ||
----------------
as4230 wrote:

I needed something to cover the stack argument cases. I saw some usage for bookkeeping but no usage for the way I use it here. I don't need to argue for it though because I like your idea better. The stack argument slots are stride aligned so `LDBase->getBaseAlign() >= Align(WideEltBits / 8)` covers them and is easier to follow. 

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


More information about the llvm-commits mailing list