OLD | NEW |
(Empty) | |
| 1 ; RUN: opt %s -pnacl-sjlj-eh -S | FileCheck %s |
| 2 |
| 3 ; Example std::type_info objects. |
| 4 @exc_typeid1 = external global i8 |
| 5 @exc_typeid2 = external global i8 |
| 6 @exc_typeid3 = external global i8 |
| 7 |
| 8 ; This must be declared for "-pnacl-sjlj-eh" to work. |
| 9 @__pnacl_eh_stack = external thread_local global i8* |
| 10 |
| 11 declare i32 @llvm.eh.typeid.for(i8*) |
| 12 |
| 13 declare void @external_func() |
| 14 |
| 15 |
| 16 @__pnacl_eh_type_table = external global i8* |
| 17 @__pnacl_eh_action_table = external global i8* |
| 18 @__pnacl_eh_filter_table = external global i8* |
| 19 |
| 20 ; CHECK: %action_table_entry = type { i32, i32 } |
| 21 |
| 22 ; CHECK: @__pnacl_eh_type_table = internal constant [4 x i8*] [i8* @exc_typeid1,
i8* @exc_typeid2, i8* @exc_typeid3, i8* null] |
| 23 |
| 24 ; CHECK: @__pnacl_eh_action_table = internal constant [6 x %action_table_entry]
[%action_table_entry { i32 2, i32 0 }, %action_table_entry { i32 1, i32 1 }, %ac
tion_table_entry { i32 0, i32 2 }, %action_table_entry { i32 -1, i32 0 }, %actio
n_table_entry { i32 -2, i32 0 }, %action_table_entry { i32 3, i32 0 }] |
| 25 |
| 26 ; CHECK: @__pnacl_eh_filter_table = internal constant [5 x i32] [i32 -1, i32 1,
i32 2, i32 0, i32 -1] |
| 27 |
| 28 |
| 29 ; Exception type pointers are allocated IDs which specify the index |
| 30 ; into __pnacl_eh_type_table where the type may be found. |
| 31 define void @test_eh_typeid(i32 %arg) { |
| 32 %id1 = call i32 @llvm.eh.typeid.for(i8* @exc_typeid1) |
| 33 %id2 = call i32 @llvm.eh.typeid.for(i8* @exc_typeid2) |
| 34 %id3 = call i32 @llvm.eh.typeid.for(i8* @exc_typeid3) |
| 35 %cmp1 = icmp eq i32 %arg, %id1 |
| 36 %cmp2 = icmp eq i32 %arg, %id2 |
| 37 %cmp3 = icmp eq i32 %arg, %id3 |
| 38 ret void |
| 39 } |
| 40 ; CHECK: define void @test_eh_typeid |
| 41 ; CHECK-NEXT: %cmp1 = icmp eq i32 %arg, 0 |
| 42 ; CHECK-NEXT: %cmp2 = icmp eq i32 %arg, 1 |
| 43 ; CHECK-NEXT: %cmp3 = icmp eq i32 %arg, 2 |
| 44 ; CHECK-NEXT: ret void |
| 45 |
| 46 |
| 47 define void @test_single_catch_clause() { |
| 48 invoke void @external_func() to label %cont unwind label %lpad |
| 49 cont: |
| 50 ret void |
| 51 lpad: |
| 52 landingpad i32 personality i8* null |
| 53 catch i8* @exc_typeid3 |
| 54 ret void |
| 55 } |
| 56 ; CHECK: define void @test_single_catch_clause |
| 57 ; CHECK: store i32 1, i32* %exc_info_ptr |
| 58 |
| 59 |
| 60 define void @test_multiple_catch_clauses() { |
| 61 invoke void @external_func() to label %cont unwind label %lpad |
| 62 cont: |
| 63 ret void |
| 64 lpad: |
| 65 landingpad i32 personality i8* null |
| 66 catch i8* @exc_typeid1 |
| 67 catch i8* @exc_typeid2 |
| 68 catch i8* @exc_typeid3 |
| 69 ret void |
| 70 } |
| 71 ; CHECK: define void @test_multiple_catch_clauses |
| 72 ; CHECK: store i32 3, i32* %exc_info_ptr |
| 73 |
| 74 |
| 75 define void @test_empty_filter_clause() { |
| 76 invoke void @external_func() to label %cont unwind label %lpad |
| 77 cont: |
| 78 ret void |
| 79 lpad: |
| 80 landingpad i32 personality i8* null |
| 81 filter [0 x i8*] [] |
| 82 ret void |
| 83 } |
| 84 ; CHECK: define void @test_empty_filter_clause |
| 85 ; CHECK: store i32 4, i32* %exc_info_ptr |
| 86 |
| 87 |
| 88 define void @test_filter_clause() { |
| 89 invoke void @external_func() to label %cont unwind label %lpad |
| 90 cont: |
| 91 ret void |
| 92 lpad: |
| 93 landingpad i32 personality i8* null |
| 94 filter [3 x i8*] [i8* @exc_typeid2, |
| 95 i8* @exc_typeid3, |
| 96 i8* @exc_typeid1] |
| 97 ret void |
| 98 } |
| 99 ; CHECK: define void @test_filter_clause |
| 100 ; CHECK: store i32 5, i32* %exc_info_ptr |
| 101 |
| 102 |
| 103 ; "catch i8* null" means that any C++ exception matches. |
| 104 define void @test_catch_all_clause() { |
| 105 invoke void @external_func() to label %cont unwind label %lpad |
| 106 cont: |
| 107 ret void |
| 108 lpad: |
| 109 landingpad i32 personality i8* null |
| 110 catch i8* null |
| 111 ret void |
| 112 } |
| 113 ; CHECK: define void @test_catch_all_clause |
| 114 ; CHECK: store i32 6, i32* %exc_info_ptr |
| 115 |
| 116 |
| 117 ; "cleanup" is treated the same as "catch i8* null". |
| 118 define void @test_cleanup_clause() { |
| 119 invoke void @external_func() to label %cont unwind label %lpad |
| 120 cont: |
| 121 ret void |
| 122 lpad: |
| 123 landingpad i32 personality i8* null |
| 124 cleanup |
| 125 ret void |
| 126 } |
| 127 ; CHECK: define void @test_cleanup_clause |
| 128 ; CHECK: store i32 6, i32* %exc_info_ptr |
OLD | NEW |