This is an archive of the discontinued LLVM Phabricator instance.

Remove assertion on CFI stack
DraftPublic

Authored by rafauler on Mar 27 2023, 11:41 PM.
This is a draft revision that has not yet been submitted for review.

Details

Reviewers
Amir
maksfb
Summary

This assertion requires that we have an exact number of
remember/restore CFIs. That is unnecessarily strict. We should only
assert that we have more remember instructions than restore ones.

Fixes #61721

Diff Detail

Event Timeline

rafauler created this revision.Mar 27 2023, 11:41 PM
Herald added a reviewer: maksfb. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
Herald added a subscriber: ayermolo. · View Herald Transcript
yota9 added a subscriber: yota9.Mar 28 2023, 12:05 PM
yota9 added inline comments.
bolt/lib/Core/BinaryFunction.cpp
2415

Just wondering - we are not interested in operation types that might be in state stack? E.g. are we only expect to have OpRestoreState here or any kind?

rafauler added inline comments.Mar 29 2023, 11:16 AM
bolt/lib/Core/BinaryFunction.cpp
2415

What happens is that the CFI code may have RememberState at any given point in order to easily encode the CFI in another, future point of the function, but may decide to just never restore it if the compiler is not very careful. And the standard allows that. From the point of view of the unwinder, it doesn't care if some state was saved but never used anywhere, so should we.

hzq added a subscriber: hzq.May 3 2023, 11:49 PM
sinan added a subscriber: sinan.May 29 2023, 8:53 PM

Hi,

any progress on this patch? Those who try to bolt a program built by clang in AArch64 are likely encounters this unnecessary assertion failure.

  1. CFIFixup is turned on in AArch64 and it could emit remember/restore cfi directives
  1. AsmPrinter::emitCFIInstruction do not emit the restore cfi directive if the cfi directive is beyond the end of the function(e.g. this restore cfi is placed inside an empty basic block, which is put at the end of the function).
void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {
  ... ...
  // If there is no "real" instruction following this CFI instruction, skip
  // emitting it; it would be beyond the end of the function's FDE range.
  auto *MBB = MI.getParent();
  auto I = std::next(MI.getIterator());
  while (I != MBB->end() && I->isTransient())
    ++I;
  if (I == MBB->instr_end() &&
      MBB->getReverseIterator() == MBB->getParent()->rbegin())
    return;

#61971 is another issue encountered this problem.