[llvm] [VectorCombine] Fold contiguous loads into a single vector load (PR #185736)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 8 02:18:19 PDT 2026


================
@@ -6131,6 +6055,203 @@ bool VectorCombine::shrinkPhiOfShuffles(Instruction &I) {
   return true;
 }
 
+static GEPNoWrapFlags getConstantGEPNoWrapFlagsToBase(Value *Ptr, Value *Base,
+                                                      const DataLayout &DL) {
+  std::optional<GEPNoWrapFlags> Flags;
+  while (Ptr != Base) {
+    auto *GEP = dyn_cast<GEPOperator>(Ptr);
+    if (!GEP)
+      return GEPNoWrapFlags::none();
+
+    APInt Offset(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
+    if (!GEP->accumulateConstantOffset(DL, Offset))
+      return GEPNoWrapFlags::none();
+
+    Flags = Flags ? Flags->intersectForOffsetAdd(GEP->getNoWrapFlags())
+                  : GEP->getNoWrapFlags();
+    Ptr = GEP->getPointerOperand();
+  }
+
+  return Flags.value_or(GEPNoWrapFlags::none());
+}
+
+/// Try to fold lanes assembled from contiguous vector-load elements into one
+/// load of the result type.
+///
+///   1. Trace lanes:
+///      result lane 0   result lane 1   ...   result lane N
+///           |               |                       |
+///           +------- look through shuffles ---------+
+///                           |
+///                 source load + source lane
+///
+///   2. Check layout:
+///                 same base pointer and contiguous offsets?
+///
+///   3. Model old cost:
+///                 current op + unique loads + original GEPs
+///
+///   4. Model new cost:
+///                 ptradd(base, start byte offset) + one vector load
+///
+///   5. Replace:
+///                 if NewCost is cheaper
+///
+/// For example:
+///
+///   %p = getelementptr float, ptr %base, i64 4
+///   %v = load <4 x float>, ptr %p
+///          base+16   base+20   base+24   base+28
+///          lane 0    lane 1    lane 2    lane 3
+///                              |         |
+///                              +---------+  contiguous
+///                                  |
+///   %r = shufflevector %v, poison, <2, 3>
+///                                  |
+///                                  v
+///   %q = getelementptr i8, ptr %base, i64 24
+///   %r = load <2 x float>, ptr %q
+bool VectorCombine::foldContiguousLoads(Instruction &I) {
+  auto *VT = dyn_cast<FixedVectorType>(I.getType());
+  if (!VT || I.use_empty())
+    return false;
+
+  Type *EltTy = VT->getElementType();
+  if (!DL->typeSizeEqualsStoreSize(EltTy))
+    return false;
+
+  uint64_t ElementSizeBits = DL->getTypeStoreSizeInBits(EltTy);
+  if (ElementSizeBits % 8 != 0)
+    return false;
+  uint64_t ElementSizeBytes = ElementSizeBits / 8;
----------------
RKSimon wrote:

```suggestion
  uint64_t ElementSizeBytes = DL->getTypeStoreSize(EltTy);
```

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


More information about the llvm-commits mailing list