blob: df1ba0c826dfc76ec78fc5f009efdab85111a288 [file] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; RUN: wasm-opt %s -all --merge-blocks -all -S -o - | filecheck %s
(module
;; CHECK: (import "a" "b" (func $import (type $0)))
(import "a" "b" (func $import))
;; CHECK: (tag $empty (type $0))
(tag $empty)
;; CHECK: (tag $i32 (type $1) (param i32))
(tag $i32 (param i32))
;; CHECK: (tag $exnref (type $2) (param exnref))
(tag $exnref (param exnref))
;; CHECK: (func $drop-block-try_catch_all_ref (type $0)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch_all $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch_all_ref
;; This block is dropped, so the try_table's exnref value can be removed
;; by replacing catch_all_ref with catch_all.
(drop
(block $catch (result exnref)
(try_table (catch_all_ref $catch)
(call $import)
(unreachable)
)
)
)
)
;; CHECK: (func $drop-block-try_catch_ref (type $0)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch $empty $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch_ref
;; As above, but with catch_ref instead of catch_all_ref. We can still
;; optimize.
(drop
(block $catch (result exnref)
(try_table (catch_ref $empty $catch)
(call $import)
(unreachable)
)
)
)
)
;; CHECK: (func $drop-block-try_catch_multi (type $0)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch $empty $catch) (catch_all $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch_multi
;; As above, but with two catches, both of whom can be optimized.
(drop
(block $catch (result exnref)
(try_table (catch_ref $empty $catch) (catch_all_ref $catch)
(call $import)
(unreachable)
)
)
)
)
;; CHECK: (func $drop-block-try_catch_all_i32 (type $0)
;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (block $catch (type $3) (result i32 exnref)
;; CHECK-NEXT: (try_table (catch_ref $i32 $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch_all_i32
;; Send a tag value + exnref. We don't handle this yet TODO
(tuple.drop 2
(block $catch (result i32 exnref)
(try_table (catch_ref $i32 $catch)
(call $import)
(unreachable)
)
)
)
)
;; CHECK: (func $drop-block-try_catch_multi_partial (type $0)
;; CHECK-NEXT: (tuple.drop 2
;; CHECK-NEXT: (block $outer (type $4) (result i32 (ref exn))
;; CHECK-NEXT: (block $inner
;; CHECK-NEXT: (try_table (catch_ref $i32 $outer) (catch_all $inner)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch_multi_partial
;; Two catches, one of which we can optimize, but not both.
(tuple.drop 2
(block $outer (result i32 exnref)
(drop
(block $inner (result exnref)
(try_table (catch_ref $i32 $outer) (catch_all_ref $inner)
(call $import)
(unreachable)
)
)
)
(unreachable)
)
)
)
;; CHECK: (func $drop-block_try_catch_multi-fail (type $0)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block $catch (result exnref)
;; CHECK-NEXT: (try_table (catch $exnref $catch) (catch_all_ref $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block_try_catch_multi-fail
(drop
;; This block is sent an exnref in two ways: once as the contents of a tag
;; and once as the ref of a catch_all_ref. We can remove the latter but
;; not the former, and they go to the same block, so we cannot optimize.
(block $catch (result exnref)
(try_table (catch $exnref $catch) (catch_all_ref $catch)
(call $import)
(unreachable)
)
)
)
)
;; CHECK: (func $drop-block-try_catch_all (type $0)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch_all $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch_all
;; Without _ref, there is nothing to optimize (and we should not error).
;; Also since there is no ref, there is no drop anyhow.
(block $catch
(try_table (catch_all $catch)
(call $import)
(unreachable)
)
)
)
;; CHECK: (func $drop-block-try_catch (type $0)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch $empty $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch
;; As above, but with a catch instead of catch_all.
(block $catch
(try_table (catch $empty $catch)
(call $import)
(unreachable)
)
)
)
;; CHECK: (func $drop-block-try_catch_i32 (type $0)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block $catch (result i32)
;; CHECK-NEXT: (try_table (catch $i32 $catch)
;; CHECK-NEXT: (call $import)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $drop-block-try_catch_i32
;; Send an i32 without a ref. We can't optimize here, as we can't prevent
;; the i32 from being sent.
(drop
(block $catch (result i32)
(try_table (catch $i32 $catch)
(call $import)
(unreachable)
)
)
)
)
)