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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@246752
91177308-0d34-0410-b5e6-
96231b3b80d8
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
---------------
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``:
[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], []>;
"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;
+ }
};
}
--- /dev/null
+; 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(...)
--- /dev/null
+; 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(...)