[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