Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1478)

Unified Diff: test/Transforms/NaCl/pnacl-sjlj-eh.ll

Issue 24777002: Add PNaClSjLjEH pass to implement C++ exception handling using setjmp()+longjmp() (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Retry upload Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/Transforms/NaCl/pnacl-eh-exception-info.ll ('k') | tools/opt/opt.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/Transforms/NaCl/pnacl-sjlj-eh.ll
diff --git a/test/Transforms/NaCl/pnacl-sjlj-eh.ll b/test/Transforms/NaCl/pnacl-sjlj-eh.ll
new file mode 100644
index 0000000000000000000000000000000000000000..3783b08a5edc339c4762ae8710067015b311d7db
--- /dev/null
+++ b/test/Transforms/NaCl/pnacl-sjlj-eh.ll
@@ -0,0 +1,127 @@
+; RUN: opt %s -pnacl-sjlj-eh -S | FileCheck %s
+
+; This must be declared for expanding "invoke" and "landingpad" instructions.
+@__pnacl_eh_stack = external thread_local global i8*
+
+; This must be declared for expanding "resume" instructions.
+declare void @__pnacl_eh_resume(i32* %exception)
+
+declare i32 @external_func(i64 %arg)
+
+
+; CHECK: %ExceptionFrame = type { [1024 x i8], %ExceptionFrame*, i32 }
+
+define i32 @invoke_test(i64 %arg) {
+ %result = invoke i32 @external_func(i64 %arg)
+ to label %cont unwind label %lpad
+cont:
+ ret i32 %result
+lpad:
+ %lp = landingpad { i8*, i32 } personality i8* null cleanup
+ ret i32 999
+}
+; CHECK: define i32 @invoke_test
+; CHECK-NEXT: %invoke_frame = alloca %ExceptionFrame, align 8
+; CHECK-NEXT: %exc_info_ptr = getelementptr %ExceptionFrame* %invoke_frame, i32 0, i32 2
+; CHECK-NEXT: %invoke_next = getelementptr %ExceptionFrame* %invoke_frame, i32 0, i32 1
+; CHECK-NEXT: %invoke_jmp_buf = getelementptr %ExceptionFrame* %invoke_frame, i32 0, i32 0, i32 0
+; CHECK-NEXT: %pnacl_eh_stack = bitcast i8** @__pnacl_eh_stack to %ExceptionFrame**
+; CHECK-NEXT: %invoke_sj = call i32 @llvm.nacl.setjmp(i8* %invoke_jmp_buf)
+; CHECK-NEXT: %invoke_sj_is_zero = icmp eq i32 %invoke_sj, 0
+; CHECK-NEXT: br i1 %invoke_sj_is_zero, label %invoke_do_call, label %lpad
+; CHECK: invoke_do_call:
+; CHECK-NEXT: %old_eh_stack = load %ExceptionFrame** %pnacl_eh_stack
+; CHECK-NEXT: store %ExceptionFrame* %old_eh_stack, %ExceptionFrame** %invoke_next
+; CHECK-NEXT: store i32 {{[0-9]+}}, i32* %exc_info_ptr
+; CHECK-NEXT: store %ExceptionFrame* %invoke_frame, %ExceptionFrame** %pnacl_eh_stack
+; CHECK-NEXT: %result = call i32 @external_func(i64 %arg)
+; CHECK-NEXT: store %ExceptionFrame* %old_eh_stack, %ExceptionFrame** %pnacl_eh_stack
+; CHECK-NEXT: br label %cont
+; CHECK: cont:
+; CHECK-NEXT: ret i32 %result
+; CHECK: lpad:
+; CHECK-NEXT: %landingpad_ptr = bitcast i8* %invoke_jmp_buf to { i8*, i32 }*
+; CHECK-NEXT: %lp = load { i8*, i32 }* %landingpad_ptr
+; CHECK-NEXT: ret i32 999
+
+
+; A landingpad block may be used by multiple "invoke" instructions.
+define i32 @shared_landingpad(i64 %arg) {
+ %result1 = invoke i32 @external_func(i64 %arg)
+ to label %cont1 unwind label %lpad
+cont1:
+ %result2 = invoke i32 @external_func(i64 %arg)
+ to label %cont2 unwind label %lpad
+cont2:
+ ret i32 %result2
+lpad:
+ %lp = landingpad { i8*, i32 } personality i8* null cleanup
+ ret i32 999
+}
+; CHECK: define i32 @shared_landingpad
+; CHECK: br i1 %invoke_sj_is_zero, label %invoke_do_call, label %lpad
+; CHECK: br i1 %invoke_sj_is_zero2, label %invoke_do_call3, label %lpad
+
+
+; Check that the pass can handle a landingpad appearing before an invoke.
+define i32 @landingpad_before_invoke() {
+ ret i32 123
+
+dead_block:
+ %lp = landingpad i32 personality i8* null cleanup
+ ret i32 %lp
+}
+; CHECK: define i32 @landingpad_before_invoke
+; CHECK: %lp = load i32* %landingpad_ptr
+
+
+; Test the expansion of the "resume" instruction.
+define void @test_resume({ i8*, i32 } %arg) {
+ resume { i8*, i32 } %arg
+}
+; CHECK: define void @test_resume
+; CHECK-NEXT: %resume_exc = extractvalue { i8*, i32 } %arg, 0
+; CHECK-NEXT: %resume_cast = bitcast i8* %resume_exc to i32*
+; CHECK-NEXT: call void @__pnacl_eh_resume(i32* %resume_cast)
+; CHECK-NEXT: unreachable
+
+
+; Check that call attributes are preserved.
+define i32 @call_attrs(i64 %arg) {
+ %result = invoke fastcc i32 @external_func(i64 inreg %arg) noreturn
+ to label %cont unwind label %lpad
+cont:
+ ret i32 %result
+lpad:
+ %lp = landingpad { i8*, i32 } personality i8* null cleanup
+ ret i32 999
+}
+; CHECK: define i32 @call_attrs
+; CHECK: %result = call fastcc i32 @external_func(i64 inreg %arg) [[NORETURN:#[0-9]+]]
+
+
+; Check that any PHI nodes referring to the result of an "invoke" are
+; updated to refer to the correct basic block.
+define i32 @invoke_with_phi_nodes(i64 %arg) {
+entry:
+ %result = invoke i32 @external_func(i64 %arg)
+ to label %cont unwind label %lpad
+cont:
+ %cont_phi = phi i32 [ 100, %entry ]
+ ret i32 %cont_phi
+lpad:
+ %lpad_phi = phi i32 [ 200, %entry ]
+ %lp = landingpad { i8*, i32 } personality i8* null cleanup
+ ret i32 %lpad_phi
+}
+; CHECK: define i32 @invoke_with_phi_nodes
+; CHECK: %result = call i32 @external_func(i64 %arg)
+; CHECK: cont:
+; CHECK-NEXT: %cont_phi = phi i32 [ 100, %invoke_do_call ]
+; CHECK-NEXT: ret i32 %cont_phi
+; CHECK: lpad:
+; CHECK-NEXT: %lpad_phi = phi i32 [ 200, %entry ]
+; CHECK: ret i32 %lpad_phi
+
+
+; CHECK: attributes [[NORETURN]] = { noreturn }
« no previous file with comments | « test/Transforms/NaCl/pnacl-eh-exception-info.ll ('k') | tools/opt/opt.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698