[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