On the past, we just check if gep's pointer operand is a non-instruction
operand or is a alloca instruction to decide if it is guaranteed to be
a loop invariant. If the gep's pointer operand is also a gep then it would
be considered to be a non-guaranteed loop invariant. This patch makes
MemorySSA Recursively checking if gep's pointer operand is guaranteed
to be a loop invariant.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
650 ms | x64 debian > LLVM.CodeGen/AMDGPU::noclobber-barrier.ll |
Event Timeline
llvm/lib/Analysis/MemorySSA.cpp | ||
---|---|---|
2635 | This recursion should not be unbounded, and preferably make it iterative. |
lgtm with comments addressed.
llvm/lib/Analysis/MemorySSA.cpp | ||
---|---|---|
2628 | The AA "look through geps" limit is 6. I don't have a strong preference on the value, I don't have any data on how frequent this will be useful.. | |
2638 | nit: Could reduce the if nesting auto *I = dyn_cast<Instruction>(Ptr); if (!I || isa<AllocaInst>(Ptr) || I->getParent()->isEntryBlock()) return true; if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) { if (!GEP->hasAllConstantIndices()) return false; Ptr = GEP->getPointerOperand(); } |
I'm curious where this came up in practice. Constant GEP based on constant GEP gets merged by InstCombine.
FWIW, we have a stripInBoundsConstantOffsets() method, which does nearly what we want here. I wonder whether it would make sense to add a new PointerStripKind for this? (I think some existing users of stripInBoundsConstantOffsets don't actually need the "inbounds" part and just end up using it because it's convenient.)
TBH, The test was constructed by hand. So it may not make sense in practice since as you said it always gets merged by InstCombine. But that reminds me if it makes sense to also check whether the index operands are invariant?
FWIW, we have a stripInBoundsConstantOffsets() method, which does nearly what we want here. I wonder whether it would make sense to add a new PointerStripKind for this? (I think some existing users of stripInBoundsConstantOffsets don't actually need the "inbounds" part and just end up using it because it's convenient.)
I think it makes sense. If I use the stripInBoundsConstantOffsets() here, I will not care about the inbounds flag.
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp#L1283 may also be a potential user if a new PointerStripKind added.
The AA "look through geps" limit is 6. I don't have a strong preference on the value, I don't have any data on how frequent this will be useful..
Would be good to use a cl::opt instead of a local constant though, for easier testing.