[llvm] LAA: clarify loop-variant GEP idx computation (PR #125315)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 1 01:40:58 PST 2025
================
@@ -2809,50 +2807,17 @@ bool LoopAccessInfo::isInvariant(Value *V) const {
return SE->isLoopInvariant(S, TheLoop);
}
-/// Find the operand of the GEP that should be checked for consecutive
-/// stores. This ignores trailing indices that have no effect on the final
-/// pointer.
-static unsigned getGEPInductionOperand(const GetElementPtrInst *Gep) {
- const DataLayout &DL = Gep->getDataLayout();
- unsigned LastOperand = Gep->getNumOperands() - 1;
- TypeSize GEPAllocSize = DL.getTypeAllocSize(Gep->getResultElementType());
-
- // Walk backwards and try to peel off zeros.
- while (LastOperand > 1 && match(Gep->getOperand(LastOperand), m_Zero())) {
- // Find the type we're currently indexing into.
- gep_type_iterator GEPTI = gep_type_begin(Gep);
- std::advance(GEPTI, LastOperand - 2);
-
- // If it's a type with the same allocation size as the result of the GEP we
- // can peel off the zero index.
- TypeSize ElemSize = GEPTI.isStruct()
- ? DL.getTypeAllocSize(GEPTI.getIndexedType())
- : GEPTI.getSequentialElementStride(DL);
- if (ElemSize != GEPAllocSize)
- break;
- --LastOperand;
- }
-
- return LastOperand;
-}
-
-/// If the argument is a GEP, then returns the operand identified by
-/// getGEPInductionOperand. However, if there is some other non-loop-invariant
-/// operand, it returns that instead.
-static Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp) {
+/// If \p Ptr is a GEP, which has a loop-variant index, return that index.
+/// Otherwise, return \p Ptr.
+static Value *getLoopVariantGEPIdx(Value *Ptr, ScalarEvolution *SE, Loop *Lp) {
auto *GEP = dyn_cast<GetElementPtrInst>(Ptr);
if (!GEP)
return Ptr;
- unsigned InductionOperand = getGEPInductionOperand(GEP);
-
- // Check that all of the gep indices are uniform except for our induction
- // operand.
- for (unsigned I = 0, E = GEP->getNumOperands(); I != E; ++I)
- if (I != InductionOperand &&
- !SE->isLoopInvariant(SE->getSCEV(GEP->getOperand(I)), Lp))
- return Ptr;
- return GEP->getOperand(InductionOperand);
+ auto *It = find_if(GEP->operands(), [&](const Use &U) {
+ return !SE->isLoopInvariant(SE->getSCEV(U), Lp);
+ });
+ return It == GEP->op_end() ? Ptr : It->get();
----------------
nikic wrote:
Don't you need to check that there is *exactly one* non-loop-invariant operand? You currently just return the first, but there might be additional loop varying operands afterwards, in which case you'll determine an incorrect stride?
https://github.com/llvm/llvm-project/pull/125315
More information about the llvm-commits
mailing list