[llvm] [NewGVN] Relax conditions when checking safety of memory accesses (PR #98609)
Nuno Lopes via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 24 01:56:05 PDT 2024
================
@@ -2597,34 +2597,61 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *V, const BasicBlock *PHIBlock,
Worklist.push_back(V);
while (!Worklist.empty()) {
auto *I = Worklist.pop_back_val();
- if (!isa<Instruction>(I))
+ if (!(isa<Instruction>(I) || isa<MemoryAccess>(I)))
continue;
auto OISIt = OpSafeForPHIOfOps.find({I, CacheIdx});
if (OISIt != OpSafeForPHIOfOps.end())
return OISIt->second;
+ // getBlockForValue only works for instructions and memoryPhis.
+ auto *IBlock = isa<MemoryUseOrDef>(I) ? cast<MemoryUseOrDef>(I)->getBlock()
+ : getBlockForValue(I);
+
// Keep walking until we either dominate the phi block, or hit a phi, or run
// out of things to check.
- if (DT->properlyDominates(getBlockForValue(I), PHIBlock)) {
+ if (DT->properlyDominates(IBlock, PHIBlock)) {
OpSafeForPHIOfOps.insert({{I, CacheIdx}, true});
continue;
}
// PHI in the same block.
- if (isa<PHINode>(I) && getBlockForValue(I) == PHIBlock) {
+ if ((isa<PHINode>(I) || isa<MemoryPhi>(I)) && IBlock == PHIBlock) {
OpSafeForPHIOfOps.insert({{I, CacheIdx}, false});
return false;
}
- auto *OrigI = cast<Instruction>(I);
- // When we hit an instruction that reads memory (load, call, etc), we must
- // consider any store that may happen in the loop. For now, we assume the
- // worst: there is a store in the loop that alias with this read.
- // The case where the load is outside the loop is already covered by the
- // dominator check above.
- // TODO: relax this condition
- if (OrigI->mayReadFromMemory())
- return false;
+ auto *OrigI = dyn_cast<Instruction>(I);
+ // When we encounter an instruction that reads memory (load, call, etc.) or
+ // a MemoryAccess, we must ensure that it does not depend on a memory Phi in
+ // PHIBlock. The base cases are already checked above; now we must check its
+ // operands.
+ MemoryAccess *MA = nullptr;
+ if (OrigI && OrigI->mayReadFromMemory())
+ MA = getMemoryAccess(OrigI);
+ else if (isa<MemoryAccess>(I))
+ MA = cast<MemoryAccess>(I);
+ if (MA) {
+ for (auto *Op : MA->operand_values()) {
+ // Null => LiveOnEntryDef
+ if (!Op)
+ continue;
+ // Stop now if we find an unsafe operand.
+ auto OISIt = OpSafeForPHIOfOps.find({OrigI, CacheIdx});
+ if (OISIt != OpSafeForPHIOfOps.end()) {
+ if (!OISIt->second) {
+ OpSafeForPHIOfOps.insert({{I, CacheIdx}, false});
----------------
nunoplopes wrote:
something is off here. I and OrigI are the same value, so the find above and this insert should have different operands.
Did you mean find(Op)?
https://github.com/llvm/llvm-project/pull/98609
More information about the llvm-commits
mailing list