[llvm] [SLP] Avoid seeding related affine loop address computations (PR #226220)

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 11 09:48:53 PDT 2026


================
@@ -1089,6 +1093,67 @@ bool isOnceUsedSeed(const Instruction *I) {
       I);
 }
 
+/// Returns true if \p Ptr is only used by scalar loads and stores, directly or
+/// through at most \p Depth levels of getelementptrs with constant offsets.
+static bool onlyFeedsScalarAccesses(Value *Ptr, bool ReVec,
+                                    unsigned Depth = 2) {
+  if (Ptr->use_empty() || Ptr->hasNUsesOrMore(UsesLimit))
+    return false;
+  return all_of(Ptr->users(), [&](User *U) {
+    if (getValueType(U, ReVec)->isVectorTy())
+      return false;
+    Value *Op;
+    if (isa<LoadInst>(U) ||
+        (match(U, m_Store(m_Value(Op), m_Specific(Ptr))) && Op != Ptr))
+      return true;
+    if (auto *GEP = dyn_cast<GetElementPtrInst>(U))
+      return Depth > 0 && GEP->getPointerOperand() == Ptr &&
+             GEP->hasAllConstantIndices() &&
+             onlyFeedsScalarAccesses(GEP, ReVec, Depth - 1);
+    return false;
+  });
+}
+
+GetElementPtrInst *getIndexChainGEP(Value *V, unsigned MaxIndexChainLength) {
+  for ([[maybe_unused]] unsigned _ : seq<unsigned>(MaxIndexChainLength)) {
+    if (!isa<BinaryOperator, CastInst>(V) || !V->hasOneUse())
+      return nullptr;
+    User *U = V->user_back();
+    if (auto *GEP = dyn_cast<GetElementPtrInst>(U))
+      return GEP->getPointerOperand() != V ? GEP : nullptr;
+    V = U;
+  }
+  return nullptr;
+}
----------------
alexey-bataev wrote:

```suggestion
void collectIndexArithmetic(Value *Index, const LoopInfo &LI,
                            SmallVectorImpl<Instruction *> &Arithmetic) {
  const Loop *L = LI.getLoopFor(cast<Instruction>(Index)->getParent());
  SmallVector<Instruction *> Worklist = {cast<Instruction>(Index)};
  while (!Worklist.empty()) {
    Instruction *I = Worklist.pop_back_val();
    Arithmetic.push_back(I);
    for (Value *Op : I->operands())
      if (isa<BinaryOperator, CastInst>(Op) && Op->hasOneUse() &&
          LI.getLoopFor(cast<Instruction>(Op)->getParent()) == L)
        Worklist.push_back(cast<Instruction>(Op));
  }
}
```
and a declaration

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


More information about the llvm-commits mailing list