[llvm] [LV] Vectorize bounded (i % 2^N) loads in read only loops w/o RT checks. (PR #207279)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 3 08:09:09 PDT 2026


================
@@ -1708,6 +1708,36 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
   return Stride;
 }
 
+uint64_t llvm::getBoundForConsecutiveLoad(const SCEV *PtrSCEV, Type *AccessTy,
+                                          const Loop *L, ScalarEvolution &SE) {
+  if (AccessTy->isScalableTy())
+    return 0;
+
+  // `A[i % 2^N]` is modeled as `Base + ElemSize * zext({0,+,1}<iN>)`by SCEV,
+  // with N being the bitwidth of the induction. For a byte element (ElemSize ==
+  // 1) the multiply folds away.
+  const SCEV *Base, *Start;
+  const APInt *Scale = nullptr;
+  auto Index = m_scev_ZExt(
+      m_scev_AffineAddRec(m_SCEV(Start), m_scev_One(), m_SpecificLoop(L)));
+  if (!match(
+          PtrSCEV,
+          m_scev_Add(m_CombineOr(Index, m_scev_Mul(m_scev_APInt(Scale), Index)),
+                     m_SCEV(Base))))
+    return 0;
----------------
artagnon wrote:

```suggestion
  const SCEV *Offset = SE.removePointerBase(PtrSCEV);
  APInt One(One, Offset->getType());
  if (!match(Offset, m_scev_Mul(m_scev_APInt(Scale), m_SCEV(Offset)))
    Scale = &One;
  if (!match(Offset, m_scev_ZExt(
      m_scev_AffineAddRec(m_SCEV(Start), m_scev_One(), m_SpecificLoop(L)))))
    return 0;
```

and strip the special case for !Scale, and non-loop-invariant Base? The suggestion may need adjusting?

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


More information about the llvm-commits mailing list