blob: 5a6a4b20b77d6834cc7c7a4c4952e4572030ed4f [file] [log] [blame] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; RUN: wasm-opt %s --vacuum -all -S -o - | filecheck %s
(module
;; CHECK: (tag $e (param i32))
(tag $e (param i32))
;; CHECK: (tag $e2 (param i32))
(tag $e2 (param i32))
;; CHECK: (func $try-test
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $try-test
;; When try body does not throw, try-body can be replaced with the try body
(try
(do
(drop (i32.const 0))
)
(catch $e
(drop (pop i32))
)
)
)
;; CHECK: (func $inner-try-catch_all-test (result i32)
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (try $try0
;; CHECK-NEXT: (do
;; CHECK-NEXT: (throw $e
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (return
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $inner-try-catch_all-test (result i32)
(local $0 i32)
;; The exception thrown in the inner try is caught by the inner catch_all,
;; so the outer try body does not throw and the outer try-catch can be
;; removed
(try
(do
(try
(do
(throw $e (i32.const 0))
)
(catch_all
(return (i32.const 1))
)
)
)
(catch $e
(drop (pop i32))
)
)
(i32.const 2)
)
;; CHECK: (func $inner-try-catch-test
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (try $try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (try $try1
;; CHECK-NEXT: (do
;; CHECK-NEXT: (throw $e2
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch $e
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (pop i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch $e
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (pop i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $inner-try-catch-test (local $0 i32)
;; The exception thrown in the inner try will not be caught by the inner
;; catch, so the outer try-catch cannot be removed
(try
(do
(try
(do
(throw $e2 (i32.const 0))
)
(catch $e
(drop (pop i32))
(local.set $0 (i32.const 1))
)
)
)
(catch $e
(drop (pop i32))
)
)
)
;; CHECK: (func $br-in-catch
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $br-in-catch
;; When catch body is removed, the removal of 'br' inside the catch body
;; should be propagated up to the outer block, so that its type will be
;; correctly updated to unreachable.
(block $label$1
(try
(do
(unreachable)
)
(catch $e
(drop (pop i32))
(br $label$1)
)
)
)
)
;; CHECK: (func $try-delegate-outer-target
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (try $label$0
;; CHECK-NEXT: (do
;; CHECK-NEXT: (try $try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (try $try2
;; CHECK-NEXT: (do
;; CHECK-NEXT: (throw $e
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (delegate $label$0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $try-delegate-outer-target
(local $0 i32)
(try $label$0 ;; outer try
(do
;; If it were not for the inner (delegate $label0), this middle try
;; cannot throw even if there is a throw in the inner try, because this
;; try has a catch_all. And Vacuum can replace the outer try-catch with
;; the try's body if the body doesn't throw.
;;
;; But because the inner try has a delegate that targets the outer try,
;; this middle try can throw, and we can't do the optimization for
;; the outer try.
(try ;; middle try
(do
(try ;; inner try
(do
(throw $e
(i32.const 0)
)
)
(delegate $label$0)
)
)
(catch_all)
)
)
)
)
;; CHECK: (func $trivial-catch-all-of-throw
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (try $try3
;; CHECK-NEXT: (do
;; CHECK-NEXT: (if
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: (throw $e
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $trivial-catch-all-of-throw (local $0 i32)
;; This try-catch's body throws, but the catch-all catches it, so the entire
;; try can be optimized out.
(try
(do
(throw $e (i32.const 0))
)
(catch_all)
)
;; Here we also have a possible trap, so we can't do it.
(try
(do
(if
(local.get $0)
(throw $e (i32.const 0))
(unreachable)
)
)
(catch_all)
)
)
)