[llvm] [DebugInfo][GVNSink] Fix #77415: GVNSink fails to optimize LLVM IR with debug info (PR #77602)
Shan Huang via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 13 04:59:55 PDT 2024
Apochens wrote:
@nikic Hi, I think I have a solution for the non-determinism issue. This issue is caused by `llvm::sort(Preds)` in function `sinkBB`. The sorted `Preds` then is used by LockstepReverseIterator `LRI`. And in function `analyzeInstructionForSinking`, `ActivePreds` assigned by `LRI.getActiveBlocks()` is appended to `Cond.Blocks`, which is passed as argument to function `sinkLastInstruction`:
```C++
unsigned GVNSink::sinkBB(BasicBlock *BBEnd) {
...
SmallVector<BasicBlock *, 4> Preds;
for (auto *B : predecessors(BBEnd)) {
auto *T = B->getTerminator();
if (isa<BranchInst>(T) || isa<SwitchInst>(T))
Preds.push_back(B);
else
return 0;
}
...
llvm::sort(Preds);
...
LockstepReverseIterator LRI(Preds);
...
while (LRI.isValid()) {
auto Cand = analyzeInstructionForSinking(LRI, InstNum, MemoryInstNum,
NeededPHIs, PHIContents);
...
}
...
for (unsigned I = 0; I < C.NumInstructions; ++I)
sinkLastInstruction(C.Blocks, InsertBB);
return C.NumInstructions;
}
```
```C++
std::optional<SinkingInstructionCandidate>
GVNSink::analyzeInstructionForSinking(LockstepReverseIterator &LRI, ...) {
...
auto &ActivePreds = LRI.getActiveBlocks();
...
SinkingInstructionCandidate Cand;
append_range(Cand.Blocks, ActivePreds);
return Cand;
}
```
So the order of basic blocks in function `sinkLastInstruction` is decided by the memory addresses of BBs in `Preds` (_ie._, `llvm::sort(Preds)`). If the addresses order of BBs change the order changes accordingly.
I think this issue can be solved by sorting BBs according to their names, instead of their memory addresses.
https://github.com/llvm/llvm-project/pull/77602
More information about the llvm-commits
mailing list