1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[WinEH] Add llvm.eh.exceptionpointer intrinsic

Summary:
This intrinsic can be used to extract a pointer to the exception caught by
a given catchpad.  Its argument has token type and must be a `catchpad`.

Also clarify ExtendingLLVM documentation regarding overloaded intrinsics.


Reviewers: majnemer, andrew.w.kaylor, sanjoy, rnk

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D12533

llvm-svn: 246752
This commit is contained in:
Joseph Tremoulet 2015-09-03 09:15:32 +00:00
parent bce9d857cc
commit 2e31412faa
6 changed files with 99 additions and 3 deletions

View File

@ -401,6 +401,20 @@ intrinsic serves as a placeholder to delimit code before a catch handler is
outlined. After the handler is outlined, this intrinsic is simply removed.
.. _llvm.eh.exceptionpointer:
``llvm.eh.exceptionpointer``
----------------------
.. code-block:: llvm
i8 addrspace(N)* @llvm.eh.padparam.pNi8(token %catchpad)
This intrinsic retrieves a pointer to the exception caught by the given
``catchpad``.
SJLJ Intrinsics
---------------

View File

@ -49,9 +49,9 @@ function and then be turned into an instruction if warranted.
Add an entry for your intrinsic. Describe its memory access characteristics
for optimization (this controls whether it will be DCE'd, CSE'd, etc). Note
that any intrinsic using the ``llvm_int_ty`` type for an argument will
be deemed by ``tblgen`` as overloaded and the corresponding suffix will
be required on the intrinsic's name.
that any intrinsic using one of the ``llvm_any*_ty`` types for an argument or
return type will be deemed by ``tblgen`` as overloaded and the corresponding
suffix will be required on the intrinsic's name.
#. ``llvm/lib/Analysis/ConstantFolding.cpp``:

View File

@ -436,6 +436,11 @@ def int_eh_begincatch : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
[NoCapture<0>, NoCapture<1>]>;
def int_eh_endcatch : Intrinsic<[], []>;
// eh.exceptionpointer returns the pointer to the exception caught by
// the given `catchpad`.
def int_eh_exceptionpointer : Intrinsic<[llvm_anyptr_ty], [llvm_token_ty],
[IntrNoMem]>;
// Represents the list of actions to take when an exception is thrown.
def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;

View File

@ -3681,6 +3681,11 @@ void Verifier::visitIntrinsicCallSite(Intrinsic::ID ID, CallSite CS) {
"gc.relocate: relocating a pointer shouldn't change its address space", CS);
break;
}
case Intrinsic::eh_exceptionpointer: {
Assert(isa<CatchPadInst>(CS.getArgOperand(0)),
"eh.exceptionpointer argument must be a catchpad", CS);
break;
}
};
}

View File

@ -0,0 +1,26 @@
; RUN: sed -e s/.T1:// %s | not opt -lint -disable-output 2>&1 | FileCheck --check-prefix=CHECK1 %s
; RUN: sed -e s/.T2:// %s | not opt -lint -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s
target triple = "x86_64-pc-windows-msvc"
declare void @f()
;T1: declare i8* @llvm.eh.exceptionpointer.p0i8(i32)
;T1:
;T1: define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
;T1: call i8* @llvm.eh.exceptionpointer.p0i8(i32 0)
;T1: ret void
;T1: }
;CHECK1: Intrinsic has incorrect argument type!
;CHECK1-NEXT: i8* (i32)* @llvm.eh.exceptionpointer.p0i8
;T2: declare i8* @llvm.eh.exceptionpointer.p0i8(token)
;T2:
;T2: define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
;T2: call i8* @llvm.eh.exceptionpointer.p0i8(token undef)
;T2: ret void
;T2: }
;CHECK2: eh.exceptionpointer argument must be a catchpad
;CHECK2-NEXT: call i8* @llvm.eh.exceptionpointer.p0i8(token undef)
declare i32 @__CxxFrameHandler3(...)

View File

@ -0,0 +1,46 @@
; RUN: opt -lint -disable-output < %s
; This test is meant to prove that the verifier does not report errors for correct
; use of the llvm.eh.exceptionpointer intrinsic.
target triple = "x86_64-pc-windows-msvc"
declare i8* @llvm.eh.exceptionpointer.p0i8(token)
declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token)
declare void @f(...)
define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
entry:
invoke void (...) @f(i32 1)
to label %exit unwind label %catchpad
catchpad:
%catch = catchpad [i32 1] to label %do_catch unwind label %catchend
do_catch:
%exn = call i8* @llvm.eh.exceptionpointer.p0i8(token %catch)
call void (...) @f(i8* %exn)
catchret %catch to label %exit
catchend:
catchendpad unwind to caller
exit:
ret void
}
define void @test2() personality i32 (...)* @ProcessManagedException {
entry:
invoke void (...) @f(i32 1)
to label %exit unwind label %catchpad
catchpad:
%catch = catchpad [i32 1] to label %do_catch unwind label %catchend
do_catch:
%exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch)
call void (...) @f(i8 addrspace(1)* %exn)
catchret %catch to label %exit
catchend:
catchendpad unwind to caller
exit:
ret void
}
declare i32 @__CxxFrameHandler3(...)
declare i32 @ProcessManagedException(...)