Skip to content

[SEH] Fix register liveness verification for EHa #76933

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
Expand Down Expand Up @@ -3347,10 +3348,37 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
OwnerLI.computeSubRangeUndefs(Undefs, LaneMask, *MRI, *Indexes);
}

bool IsEHa = MF->getMMI().getModule()->getModuleFlag("eh-asynch");
while (true) {
assert(LiveInts->isLiveInToMBB(LR, &*MFI));
// We don't know how to track physregs into a landing pad.
if (!Reg.isVirtual() && MFI->isEHPad()) {
auto IsSEHHandler = [](const MachineBasicBlock &Handler) -> bool {
if (!Handler.isMachineBlockAddressTaken())
return false;

for (const User *U : Handler.getBasicBlock()->users()) {
if (!isa<InvokeInst>(U))
continue;
const Function *Fn = cast<CallBase>(U)->getCalledFunction();
if (!Fn || !Fn->isIntrinsic())
continue;

switch (Fn->getIntrinsicID()) {
default:
continue;
case Intrinsic::seh_scope_begin:
case Intrinsic::seh_scope_end:
case Intrinsic::seh_try_begin:
case Intrinsic::seh_try_end:
return true;
}
}
return false;
};

// TODO: we don't know how to track physregs into a landing pad. For async
// EH, the virtual reg lives before scope begin, but we don't know seh scope
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get the scope through seh_scope_begin/seh_scope_end etc.?

Copy link
Contributor Author

@HaohaiWen HaohaiWen Jan 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seh_scope_begin/seh_scope_end is lowered to fall through jmp which can be eliminated.
e.g.

BB0:
  instA
  jmp BB1:
BB1:
  invoke llvm.seh.scope.begin to BB2
BB2:
  instB

Those BB0, BB1, BB2 can be optimized to

MBB0:
   EH_LABEL
   instA
   EH_LABEL
   EH_LABEL
   instB
   EH_LABEL

We don't know which MBB the BB2 is mapped to. We also don't know which EH_LABEL the llvm.seh.scope.begin locate.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I once had an idea to lower them into pseudo instructions. But maybe need more work to do.

// range of landing pad in Machine IR. Therefore don't check its liveness.
if (MFI->isEHPad() && (!Reg.isVirtual() || (IsEHa && IsSEHHandler(*MFI)))) {
if (&*MFI == EndMBB)
break;
++MFI;
Expand All @@ -3364,8 +3392,9 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// Check that VNI is live-out of all predecessors.
for (const MachineBasicBlock *Pred : MFI->predecessors()) {
SlotIndex PEnd = LiveInts->getMBBEndIdx(Pred);
// Predecessor of landing pad live-out on last call.
// Predecessor of landing pad live-out on last call for sync EH.
if (MFI->isEHPad()) {
assert(!IsEHa && "EHa may raise exception on non call");
for (const MachineInstr &MI : llvm::reverse(*Pred)) {
if (MI.isCall()) {
PEnd = Indexes->getInstructionIndex(MI).getBoundaryIndex();
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/X86/windows-seh-EHa-RegisterLiveness.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
; XFAIL: *
; RUN: llc --verify-machineinstrs < %s
source_filename = "test.cpp"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
Expand Down