Index: llvm/include/llvm/CodeGen/MachineInstr.h =================================================================== --- llvm/include/llvm/CodeGen/MachineInstr.h +++ llvm/include/llvm/CodeGen/MachineInstr.h @@ -1190,6 +1190,8 @@ return isEHLabel() || isGCLabel() || isAnnotationLabel(); } + bool isStatepoint() const { return getOpcode() == TargetOpcode::STATEPOINT; } + bool isCFIInstruction() const { return getOpcode() == TargetOpcode::CFI_INSTRUCTION; } Index: llvm/lib/Target/X86/X86AvoidTrailingCall.cpp =================================================================== --- llvm/lib/Target/X86/X86AvoidTrailingCall.cpp +++ llvm/lib/Target/X86/X86AvoidTrailingCall.cpp @@ -70,7 +70,7 @@ // expand to nothing, and some expand to code. This logic conservatively assumes // they might expand to nothing. static bool isRealInstruction(MachineInstr &MI) { - return !MI.isPseudo() && !MI.isMetaInstruction(); + return (!MI.isPseudo() && !MI.isMetaInstruction()) || MI.isStatepoint(); } // Return true if this is a call instruction, but not a tail call. Index: llvm/test/CodeGen/X86/win64-eh-trailing-statepoint.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/win64-eh-trailing-statepoint.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple=x86_64-windows-gnu %s -o - | FileCheck %s + +; CHECK: foo: +; CHECK: callq raise +; CHECK-NEXT: .Ltmp0: +; CHECK-NEXT: int3 + +define void @foo() gc "statepoint-example" personality i8* bitcast (i32 (...)* @__gxx_personality_seh0 to i8*) { + %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* elementtype(void ()) @raise, i32 0, i32 0, i32 0, i32 0) + unreachable +} + +declare void @raise() + +declare dso_local i32 @__gxx_personality_seh0(...) + +declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 immarg, i32 immarg, void ()*, i32 immarg, i32 immarg, ...)