OLD | NEW |
1 ; RUN: opt %s -pnacl-sjlj-eh -S | FileCheck %s | 1 ; RUN: opt %s -pnacl-sjlj-eh -S | FileCheck %s |
2 | 2 |
3 ; This must be declared for expanding "invoke" and "landingpad" instructions. | 3 ; This must be declared for expanding "invoke" and "landingpad" instructions. |
4 @__pnacl_eh_stack = external thread_local global i8* | 4 @__pnacl_eh_stack = external thread_local global i8* |
5 | 5 |
6 ; This must be declared for expanding "resume" instructions. | 6 ; This must be declared for expanding "resume" instructions. |
7 declare void @__pnacl_eh_resume(i32* %exception) | 7 declare void @__pnacl_eh_resume(i32* %exception) |
8 | 8 |
9 declare i32 @external_func(i64 %arg) | 9 declare i32 @external_func(i64 %arg) |
10 declare void @external_func_void() | 10 declare void @external_func_void() |
11 declare i32 @my_setjmp() | 11 declare i32 @my_setjmp() |
12 | 12 |
13 | 13 |
14 ; CHECK: %ExceptionFrame = type { [1024 x i8], %ExceptionFrame*, i32 } | 14 ; CHECK: %ExceptionFrame = type { [1024 x i8], %ExceptionFrame*, i32 } |
15 | 15 |
16 define i32 @invoke_test(i64 %arg) { | 16 define i32 @invoke_test(i64 %arg) { |
17 %result = invoke i32 @external_func(i64 %arg) | 17 %result = invoke i32 @external_func(i64 %arg) |
18 to label %cont unwind label %lpad | 18 to label %cont unwind label %lpad |
19 cont: | 19 cont: |
20 ret i32 %result | 20 ret i32 %result |
21 lpad: | 21 lpad: |
22 %lp = landingpad { i8*, i32 } personality i8* null cleanup | 22 %lp = landingpad { i8*, i32 } personality i8* null cleanup |
23 ret i32 999 | 23 ret i32 999 |
24 } | 24 } |
25 ; CHECK: define i32 @invoke_test | 25 ; CHECK: define i32 @invoke_test |
26 ; CHECK-NEXT: %invoke_result_ptr = alloca i32 | 26 ; CHECK-NEXT: %invoke_result_ptr = alloca i32 |
27 ; CHECK-NEXT: %invoke_frame = alloca %ExceptionFrame, align 8 | 27 ; CHECK-NEXT: %invoke_frame = alloca %ExceptionFrame, align 8 |
28 ; CHECK-NEXT: %exc_info_ptr = getelementptr %ExceptionFrame* %invoke_frame, i32
0, i32 2 | 28 ; CHECK-NEXT: %exc_info_ptr = getelementptr %ExceptionFrame, %ExceptionFrame* %i
nvoke_frame, i32 0, i32 2 |
29 ; CHECK-NEXT: %invoke_next = getelementptr %ExceptionFrame* %invoke_frame, i32 0
, i32 1 | 29 ; CHECK-NEXT: %invoke_next = getelementptr %ExceptionFrame, %ExceptionFrame* %in
voke_frame, i32 0, i32 1 |
30 ; CHECK-NEXT: %invoke_jmp_buf = getelementptr %ExceptionFrame* %invoke_frame, i3
2 0, i32 0, i32 0 | 30 ; CHECK-NEXT: %invoke_jmp_buf = getelementptr %ExceptionFrame, %ExceptionFrame*
%invoke_frame, i32 0, i32 0, i32 0 |
31 ; CHECK-NEXT: %pnacl_eh_stack = bitcast i8** @__pnacl_eh_stack to %ExceptionFram
e** | 31 ; CHECK-NEXT: %pnacl_eh_stack = bitcast i8** @__pnacl_eh_stack to %ExceptionFram
e** |
32 ; CHECK-NEXT: %old_eh_stack = load %ExceptionFrame** %pnacl_eh_stack | 32 ; CHECK-NEXT: %old_eh_stack = load %ExceptionFrame*, %ExceptionFrame** %pnacl_eh
_stack |
33 ; CHECK-NEXT: store %ExceptionFrame* %old_eh_stack, %ExceptionFrame** %invoke_ne
xt | 33 ; CHECK-NEXT: store %ExceptionFrame* %old_eh_stack, %ExceptionFrame** %invoke_ne
xt |
34 ; CHECK-NEXT: store i32 {{[0-9]+}}, i32* %exc_info_ptr | 34 ; CHECK-NEXT: store i32 {{[0-9]+}}, i32* %exc_info_ptr |
35 ; CHECK-NEXT: store %ExceptionFrame* %invoke_frame, %ExceptionFrame** %pnacl_eh_
stack | 35 ; CHECK-NEXT: store %ExceptionFrame* %invoke_frame, %ExceptionFrame** %pnacl_eh_
stack |
36 ; CHECK-NEXT: %invoke_is_exc = call i32 @invoke_test_setjmp_caller(i64 %arg, i32
(i64)* @external_func, i8* %invoke_jmp_buf, i32* %invoke_result_ptr) | 36 ; CHECK-NEXT: %invoke_is_exc = call i32 @invoke_test_setjmp_caller(i64 %arg, i32
(i64)* @external_func, i8* %invoke_jmp_buf, i32* %invoke_result_ptr) |
37 ; CHECK-NEXT: %result = load i32* %invoke_result_ptr | 37 ; CHECK-NEXT: %result = load i32, i32* %invoke_result_ptr |
38 ; CHECK-NEXT: store %ExceptionFrame* %old_eh_stack, %ExceptionFrame** %pnacl_eh_
stack | 38 ; CHECK-NEXT: store %ExceptionFrame* %old_eh_stack, %ExceptionFrame** %pnacl_eh_
stack |
39 ; CHECK-NEXT: %invoke_sj_is_zero = icmp eq i32 %invoke_is_exc, 0 | 39 ; CHECK-NEXT: %invoke_sj_is_zero = icmp eq i32 %invoke_is_exc, 0 |
40 ; CHECK-NEXT: br i1 %invoke_sj_is_zero, label %cont, label %lpad | 40 ; CHECK-NEXT: br i1 %invoke_sj_is_zero, label %cont, label %lpad |
41 ; CHECK: cont: | 41 ; CHECK: cont: |
42 ; CHECK-NEXT: ret i32 %result | 42 ; CHECK-NEXT: ret i32 %result |
43 ; CHECK: lpad: | 43 ; CHECK: lpad: |
44 ; CHECK-NEXT: %landingpad_ptr = bitcast i8* %invoke_jmp_buf to { i8*, i32 }* | 44 ; CHECK-NEXT: %landingpad_ptr = bitcast i8* %invoke_jmp_buf to { i8*, i32 }* |
45 ; CHECK-NEXT: %lp = load { i8*, i32 }* %landingpad_ptr | 45 ; CHECK-NEXT: %lp = load { i8*, i32 }, { i8*, i32 }* %landingpad_ptr |
46 ; CHECK-NEXT: ret i32 999 | 46 ; CHECK-NEXT: ret i32 999 |
47 | 47 |
48 ; Check definition of helper function: | 48 ; Check definition of helper function: |
49 ; CHECK: define internal i32 @invoke_test_setjmp_caller(i64 %arg, i32 (i64)* %fu
nc_ptr, i8* %jmp_buf, i32* %result_ptr) { | 49 ; CHECK: define internal i32 @invoke_test_setjmp_caller(i64 %arg, i32 (i64)* %fu
nc_ptr, i8* %jmp_buf, i32* %result_ptr) { |
50 ; CHECK-NEXT: %invoke_sj = call i32 @llvm.nacl.setjmp(i8* %jmp_buf) [[RETURNS_TW
ICE:#[0-9]+]] | 50 ; CHECK-NEXT: %invoke_sj = call i32 @llvm.nacl.setjmp(i8* %jmp_buf) [[RETURNS_TW
ICE:#[0-9]+]] |
51 ; CHECK-NEXT: %invoke_sj_is_zero = icmp eq i32 %invoke_sj, 0 | 51 ; CHECK-NEXT: %invoke_sj_is_zero = icmp eq i32 %invoke_sj, 0 |
52 ; CHECK-NEXT: br i1 %invoke_sj_is_zero, label %normal, label %exception | 52 ; CHECK-NEXT: br i1 %invoke_sj_is_zero, label %normal, label %exception |
53 ; CHECK: normal: | 53 ; CHECK: normal: |
54 ; CHECK-NEXT: %result = call i32 %func_ptr(i64 %arg) | 54 ; CHECK-NEXT: %result = call i32 %func_ptr(i64 %arg) |
55 ; CHECK-NEXT: store i32 %result, i32* %result_ptr | 55 ; CHECK-NEXT: store i32 %result, i32* %result_ptr |
(...skipping 22 matching lines...) Expand all Loading... |
78 | 78 |
79 ; Check that the pass can handle a landingpad appearing before an invoke. | 79 ; Check that the pass can handle a landingpad appearing before an invoke. |
80 define i32 @landingpad_before_invoke() { | 80 define i32 @landingpad_before_invoke() { |
81 ret i32 123 | 81 ret i32 123 |
82 | 82 |
83 dead_block: | 83 dead_block: |
84 %lp = landingpad i32 personality i8* null cleanup | 84 %lp = landingpad i32 personality i8* null cleanup |
85 ret i32 %lp | 85 ret i32 %lp |
86 } | 86 } |
87 ; CHECK: define i32 @landingpad_before_invoke | 87 ; CHECK: define i32 @landingpad_before_invoke |
88 ; CHECK: %lp = load i32* %landingpad_ptr | 88 ; CHECK: %lp = load i32, i32* %landingpad_ptr |
89 | 89 |
90 | 90 |
91 ; Test the expansion of the "resume" instruction. | 91 ; Test the expansion of the "resume" instruction. |
92 define void @test_resume({ i8*, i32 } %arg) { | 92 define void @test_resume({ i8*, i32 } %arg) { |
93 resume { i8*, i32 } %arg | 93 resume { i8*, i32 } %arg |
94 } | 94 } |
95 ; CHECK: define void @test_resume | 95 ; CHECK: define void @test_resume |
96 ; CHECK-NEXT: %resume_exc = extractvalue { i8*, i32 } %arg, 0 | 96 ; CHECK-NEXT: %resume_exc = extractvalue { i8*, i32 } %arg, 0 |
97 ; CHECK-NEXT: %resume_cast = bitcast i8* %resume_exc to i32* | 97 ; CHECK-NEXT: %resume_cast = bitcast i8* %resume_exc to i32* |
98 ; CHECK-NEXT: call void @__pnacl_eh_resume(i32* %resume_cast) | 98 ; CHECK-NEXT: call void @__pnacl_eh_resume(i32* %resume_cast) |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 ret void | 164 ret void |
165 } | 165 } |
166 ; CHECK: define void @invoke_setjmp() | 166 ; CHECK: define void @invoke_setjmp() |
167 ; CHECK-NOT: call | 167 ; CHECK-NOT: call |
168 ; CHECK: %x = call i32 @my_setjmp() [[RETURNS_TWICE]] | 168 ; CHECK: %x = call i32 @my_setjmp() [[RETURNS_TWICE]] |
169 ; CHECK-NEXT: br label %cont | 169 ; CHECK-NEXT: br label %cont |
170 | 170 |
171 | 171 |
172 ; CHECK: attributes [[RETURNS_TWICE]] = { returns_twice } | 172 ; CHECK: attributes [[RETURNS_TWICE]] = { returns_twice } |
173 ; CHECK: attributes [[NORETURN]] = { noreturn } | 173 ; CHECK: attributes [[NORETURN]] = { noreturn } |
OLD | NEW |