| ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. |
| ;; RUN: wasm-opt %s --dce -all -S -o - | filecheck %s |
| |
| ;; If either try_table body or any of catch handler is reachable, the whole |
| ;; try_table construct is reachable. |
| (module |
| ;; CHECK: (tag $e) |
| (tag $e) |
| |
| ;; CHECK: (tag $e-i32 (param i32)) |
| (tag $e-i32 (param i32)) |
| |
| ;; CHECK: (func $foo (type $0) |
| ;; CHECK-NEXT: (nop) |
| ;; CHECK-NEXT: ) |
| (func $foo) |
| |
| ;; CHECK: (func $try_table_unreachable (type $0) |
| ;; CHECK-NEXT: (block $catch |
| ;; CHECK-NEXT: (try_table (catch_all $catch) |
| ;; CHECK-NEXT: (unreachable) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (call $foo) |
| ;; CHECK-NEXT: ) |
| (func $try_table_unreachable |
| (block $catch |
| (try_table (catch_all $catch) |
| (unreachable) |
| ) |
| ) |
| (call $foo) ;; shouldn't be dce'd |
| ) |
| |
| ;; CHECK: (func $catch_unreachable (type $0) |
| ;; CHECK-NEXT: (block $tryend |
| ;; CHECK-NEXT: (block $catch |
| ;; CHECK-NEXT: (try_table (catch_all $catch) |
| ;; CHECK-NEXT: (br $tryend) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (unreachable) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (call $foo) |
| ;; CHECK-NEXT: ) |
| (func $catch_unreachable |
| (block $tryend |
| (block $catch |
| (try_table (catch_all $catch) |
| (br $tryend) |
| ) |
| ) |
| (unreachable) |
| ) |
| (call $foo) ;; shouldn't be dce'd |
| ) |
| |
| ;; CHECK: (func $both_unreachable (type $0) |
| ;; CHECK-NEXT: (block $tryend |
| ;; CHECK-NEXT: (block $catch |
| ;; CHECK-NEXT: (try_table (catch_all $catch) |
| ;; CHECK-NEXT: (unreachable) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (unreachable) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| (func $both_unreachable |
| (block $tryend |
| (block $catch |
| (try_table (catch_all $catch) |
| (unreachable) |
| ) |
| ) |
| (unreachable) |
| ) |
| (call $foo) ;; should be dce'd |
| ) |
| |
| ;; CHECK: (func $throw (type $0) |
| ;; CHECK-NEXT: (block $label$0 |
| ;; CHECK-NEXT: (block $label$1 |
| ;; CHECK-NEXT: (throw $e) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| (func $throw |
| ;; All these wrapping expressions before 'throw' will be dce'd. |
| (drop |
| (block $label$0 (result externref) |
| (if |
| (i32.clz |
| (block $label$1 (result i32) |
| (throw $e) |
| ) |
| ) |
| (then |
| (nop) |
| ) |
| ) |
| (ref.null extern) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: (func $throw_ref (type $0) |
| ;; CHECK-NEXT: (local $ex exnref) |
| ;; CHECK-NEXT: (block $tryend |
| ;; CHECK-NEXT: (local.set $ex |
| ;; CHECK-NEXT: (block $catch (result exnref) |
| ;; CHECK-NEXT: (try_table (catch_all_ref $catch) |
| ;; CHECK-NEXT: (br $tryend) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (block |
| ;; CHECK-NEXT: (drop |
| ;; CHECK-NEXT: (i32.const 0) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: (throw_ref |
| ;; CHECK-NEXT: (local.get $ex) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| ;; CHECK-NEXT: ) |
| (func $throw_ref |
| (local $ex exnref) |
| (block $tryend |
| (local.set $ex |
| (block $catch (result exnref) |
| (try_table (catch_all_ref $catch) |
| (br $tryend) |
| ) |
| ) |
| ) |
| (drop |
| ;; This i32.add will be dce'd. |
| (i32.add |
| (i32.const 0) |
| (throw_ref (local.get $ex)) |
| ) |
| ) |
| ) |
| ) |
| ) |