[WinEH] Emit int3 after noreturn calls on Win64
authorReid Kleckner <rnk@google.com>
Wed, 30 Sep 2015 23:09:23 +0000 (23:09 +0000)
committerReid Kleckner <rnk@google.com>
Wed, 30 Sep 2015 23:09:23 +0000 (23:09 +0000)
commit39b3d70179e9ee0d8770aa08bc2400b5fdcc9aa1
treee0b05572a4f37a668e92ac6da73160dabf77df41
parentd741fc02b0fdabe236b978db24ae31c033392edf
[WinEH] Emit int3 after noreturn calls on Win64

The Win64 unwinder disassembles forwards from each PC to try to
determine if this PC is in an epilogue. If so, it skips calling the EH
personality function for that frame. Typically, this means you cannot
catch an exception in the same frame that you threw it, because 'throw'
calls a noreturn runtime function.

Previously we avoided this problem with the TrapUnreachable
TargetOption, but that's a much bigger hammer than we need. All we need
is a 1 byte non-epilogue instruction right after the call.  Instead,
what we got was an unconditional branch to a shared block containing the
ud2, potentially 7 bytes instead of 1. So, this reverts r206684, which
added TrapUnreachable, and replaces it with something better.

The new code pattern matches for invoke/call followed by unreachable and
inserts an int3 into the DAG. To be 100% watertight, we would need to
insert SEH_Epilogue instructions into all basic blocks ending in a call
with no terminators or successors, but in practice this is unlikely to
come up.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248959 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/Target/TargetOptions.h
lib/CodeGen/SelectionDAG/FastISel.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86TargetMachine.cpp
test/CodeGen/X86/br-fold.ll
test/CodeGen/X86/win-catchpad-rethrow.ll [new file with mode: 0644]
test/CodeGen/X86/win64_call_epi.ll