diff options
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp | 2 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/eh-unknown.ll | 32 |
3 files changed, 48 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d72cf592298..4391e80c6cc 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -949,6 +949,18 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) { MCConstantExpr::create(FrameOffset, OutContext)); } +static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF, + MachineModuleInfo *MMI) { + if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo()) + return true; + + // We might emit an LSDA anyway if we have an EH personality. + const Constant *PerFn = MF.getFunction()->getPersonalityFn(); + if (!PerFn) + return false; + return !isNoOpWithoutInvoke(classifyEHPersonality(PerFn)); +} + /// EmitFunctionBody - This method emits the body and trailer for a /// function. void AsmPrinter::EmitFunctionBody() { @@ -1076,8 +1088,8 @@ void AsmPrinter::EmitFunctionBody() { // Emit target-specific gunk after the function body. EmitFunctionBodyEnd(); - if (!MF->getLandingPads().empty() || MMI->hasDebugInfo() || - MF->hasEHFunclets() || MAI->hasDotTypeDotSizeDirective()) { + if (needFuncLabelsForEHOrDebugInfo(*MF, MMI) || + MAI->hasDotTypeDotSizeDirective()) { // Create a symbol for the end of function. CurrentFnEnd = createTempSymbol("func_end"); OutStreamer->EmitLabel(CurrentFnEnd); @@ -1402,8 +1414,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { CurrentFnBegin = nullptr; CurExceptionSym = nullptr; bool NeedsLocalForSize = MAI->needsLocalForSize(); - if (!MF.getLandingPads().empty() || MMI->hasDebugInfo() || - MF.hasEHFunclets() || NeedsLocalForSize) { + if (needFuncLabelsForEHOrDebugInfo(MF, MMI) || NeedsLocalForSize) { CurrentFnBegin = createTempSymbol("func_begin"); if (NeedsLocalForSize) CurrentFnSymForSize = CurrentFnBegin; diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp index 0a4a7a06cb2..e14d5be1177 100644 --- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp @@ -309,7 +309,7 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, // If some instruction between the previous try-range and the end of the // function may throw, create a call-site entry with no landing pad for the // region following the try-range. - if (SawPotentiallyThrowing && !IsSJLJ && LastLabel != nullptr) { + if (SawPotentiallyThrowing && !IsSJLJ) { CallSiteEntry Site = { LastLabel, nullptr, nullptr, 0 }; CallSites.push_back(Site); } diff --git a/llvm/test/CodeGen/X86/eh-unknown.ll b/llvm/test/CodeGen/X86/eh-unknown.ll new file mode 100644 index 00000000000..7c495bdadc6 --- /dev/null +++ b/llvm/test/CodeGen/X86/eh-unknown.ll @@ -0,0 +1,32 @@ +; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s + +; An unknown personality forces us to emit an Itanium LSDA. Make sure that the +; Itanium call site table actually tells the personality to keep unwinding, +; i.e. we have an entry and it says "has no landing pad". + +declare void @throwit() +declare void @__unknown_ehpersonality(...) + +define void @use_unknown_ehpersonality() + personality void (...)* @__unknown_ehpersonality { +entry: + call void @throwit() + unreachable +} + +; CHECK-LABEL: use_unknown_ehpersonality: +; CHECK: .Lfunc_begin0: +; CHECK: .seh_handler __unknown_ehpersonality, @unwind, @except +; CHECK: callq throwit +; CHECK: .Lfunc_end0: +; CHECK: .seh_handlerdata +; CHECK: .Lexception0: +; CHECK: .byte 255 # @LPStart Encoding = omit +; CHECK: .byte 0 # @TType Encoding = absptr +; CHECK: .asciz "\217\200" # @TType base offset +; CHECK: .byte 3 # Call site Encoding = udata4 +; CHECK: .byte 13 # Call site table length +; CHECK: .long .Lfunc_begin0-.Lfunc_begin0 # >> Call Site 1 << +; CHECK: .long .Lfunc_end0-.Lfunc_begin0 # Call between .Lfunc_begin0 and .Lfunc_end0 +; CHECK: .long 0 # has no landing pad +; CHECK: .byte 0 # On action: cleanup |