[llvm] [LAA] Rework getStrideFromPointer, speculate more (PR #212816)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 3 05:17:59 PDT 2026


================
@@ -3043,80 +3043,60 @@ bool LoopAccessInfo::isInvariant(Value *V) const {
   return SE->isLoopInvariant(S, TheLoop);
 }
 
-/// If \p Ptr is a GEP, which has a loop-variant operand, return that operand.
-/// Otherwise, return \p Ptr.
-static Value *getLoopVariantGEPOperand(Value *Ptr, ScalarEvolution *SE,
-                                       Loop *Lp) {
-  auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
-  if (!GEP)
-    return Ptr;
-
-  Value *V = Ptr;
-  for (const Use &U : GEP->operands()) {
-    if (!SE->isLoopInvariant(SE->getSCEV(U), Lp)) {
-      if (V == Ptr)
-        V = U;
-      else
-        // There must be exactly one loop-variant operand.
-        return Ptr;
-    }
-  }
-  return V;
-}
-
 /// Get the stride of a pointer access in a loop. Looks for symbolic
 /// strides "a[i*stride]". Returns the symbolic stride, or null otherwise.
-static const SCEV *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp) {
-  auto *PtrTy = dyn_cast<PointerType>(Ptr->getType());
-  if (!PtrTy)
-    return nullptr;
-
-  // Try to remove a gep instruction to make the pointer (actually index at this
-  // point) easier analyzable. If OrigPtr is equal to Ptr we are analyzing the
-  // pointer, otherwise, we are analyzing the index.
-  Value *OrigPtr = Ptr;
-
-  Ptr = getLoopVariantGEPOperand(Ptr, SE, Lp);
-  const SCEV *V = SE->getSCEV(Ptr);
-
-  if (Ptr != OrigPtr)
-    // Strip off casts.
-    while (auto *C = dyn_cast<SCEVIntegralCastExpr>(V))
-      V = C->getOperand();
-
+static const SCEV *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE,
+                                        Loop *Lp, unsigned StoreSz) {
+  assert(Ptr->getType()->isPointerTy() && "Pointer type expected");
+
+  // Get the stride of the GEP, stripping any scaling factors and casts.
+  const SCEV *V = SE->removePointerBase(SE->getSCEV(Ptr));
+  APInt One(V->getType()->getIntegerBitWidth(), 1);
+  const APInt *ScalingFactor;
+  if (!match(V, m_scev_Mul(m_scev_APInt(ScalingFactor),
+                           m_scev_IntegralCastOrSelf(m_SCEV(V)))))
+    ScalingFactor = &One;
+
+  // The stride to speculate must be the AddRec's step.
   if (!match(V, m_scev_AffineAddRec(m_SCEV(), m_SCEV(V), m_SpecificLoop(Lp))))
     return nullptr;
 
-  // Note that the restriction after this loop invariant check are only
-  // profitability restrictions.
----------------
fhahn wrote:

I think it would be worth keeping that, unless the patch changes that?

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


More information about the llvm-commits mailing list