diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp index b3e4c70eb57f3..35b7d7f508b02 100644 --- a/llvm/lib/Target/X86/X86WinEHState.cpp +++ b/llvm/lib/Target/X86/X86WinEHState.cpp @@ -363,6 +363,11 @@ void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) { Instruction *T = BB.getTerminator(); if (!isa(T)) continue; + + // If there is a musttail call, that's the de-facto terminator. + if (CallInst *CI = BB.getTerminatingMustTailCall()) + T = CI; + Builder.SetInsertPoint(T); unlinkExceptionRegistration(Builder); } diff --git a/llvm/test/CodeGen/WinEH/wineh-musttail-call.ll b/llvm/test/CodeGen/WinEH/wineh-musttail-call.ll new file mode 100644 index 0000000000000..7f508090a1bc7 --- /dev/null +++ b/llvm/test/CodeGen/WinEH/wineh-musttail-call.ll @@ -0,0 +1,32 @@ +; RUN: llc < %s | FileCheck %s + +target triple = "i386-pc-windows-msvc" + +; Check that codegen doesn't fail due to wineh inserting instructions between +; the musttail call and return instruction. + + +define void @test() personality ptr @__CxxFrameHandler3 { +; CHECK-LABEL: test: + +entry: + invoke void @foo() to label %try.cont unwind label %catch.dispatch + +catch.dispatch: + %0 = catchswitch within none [label %catch] unwind to caller + +catch: + %1 = catchpad within %0 [ptr null, i32 64, ptr null] + catchret from %1 to label %try.cont + +try.cont: +; CHECK: movl %{{[a-z0-9]+}}, %fs:0 +; CHECK: jmp _bar + + musttail call void @bar() + ret void +} + +declare i32 @__CxxFrameHandler3(...) +declare void @foo() +declare void @bar()