blob: 852ec126a92f18880019485ad0d17b60dd2486af [file] [log] [blame] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; RUN: wasm-opt %s --remove-unused-names --code-folding -all -S -o - \
;; RUN: | filecheck %s
(module
;; CHECK: (tag $e-i32 (param i32))
(tag $e-i32 (param i32))
;; CHECK: (func $pop-test (type $1)
;; CHECK-NEXT: (block $folding-inner0
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch $e-i32
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (pop i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: (br $folding-inner0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch $e-i32
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (pop i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: (br $folding-inner0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (return)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 111)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 222)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 333)
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
(func $pop-test
(try
(do
(try
(do)
(catch $e-i32
;; Expressions containing a pop should NOT be taken out and folded.
(drop (pop i32))
(drop (i32.const 111))
(drop (i32.const 222))
(drop (i32.const 333))
(unreachable)
)
)
)
(catch $e-i32
(drop (pop i32))
(drop (i32.const 111))
(drop (i32.const 222))
(drop (i32.const 333))
(unreachable)
)
)
)
;; CHECK: (func $try-call-optimize-terminating-tails-success (type $0) (result i32)
;; CHECK-NEXT: (block $folding-inner0
;; CHECK-NEXT: (return
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (br $folding-inner0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (br $folding-inner0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $try-call-optimize-terminating-tails-success (result i32)
(try
(do
;; Expressions that cannot throw can be taken out of 'try' scope.
(drop (i32.const 1))
(drop (i32.const 1))
(return (i32.const 0))
)
(catch_all
(drop (i32.const 1))
(drop (i32.const 1))
(return (i32.const 0))
)
)
(i32.const 0)
)
;; CHECK: (func $foo (type $1)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $foo)
;; CHECK: (func $try-call-optimize-terminating-tails (type $0) (result i32)
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (return
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (return
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
(func $try-call-optimize-terminating-tails (result i32)
(try
(do
;; Expressions that can throw should NOT be taken out of 'try' scope.
(call $foo)
(call $foo)
(call $foo)
(call $foo)
(return (i32.const 0))
)
(catch_all
(call $foo)
(call $foo)
(call $foo)
(call $foo)
(return (i32.const 0))
)
)
(i32.const 0)
)
;; CHECK: (func $foo-i32 (type $0) (result i32)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
(func $foo-i32 (result i32)
(i32.const 0)
)
;; CHECK: (func $try-call-optimize-terminating-tails-call-return (type $0) (result i32)
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
;; CHECK-NEXT: (call $foo-i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (return
;; CHECK-NEXT: (call $foo-i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
(func $try-call-optimize-terminating-tails-call-return (result i32)
(try
(do
(drop (i32.const 1))
(drop (i32.const 1))
;; Cannot be folded out of the try because it might throw.
(return (call $foo-i32))
)
(catch_all
(drop (i32.const 1))
(drop (i32.const 1))
(return (call $foo-i32))
)
)
(i32.const 0)
)
;; CHECK: (func $try-call-optimize-terminating-tails-return-call (type $0) (result i32)
;; CHECK-NEXT: (block $folding-inner0
;; CHECK-NEXT: (return
;; CHECK-NEXT: (block (result i32)
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (br $folding-inner0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (br $folding-inner0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (return_call $foo-i32)
;; CHECK-NEXT: )
(func $try-call-optimize-terminating-tails-return-call (result i32)
(try
(do
(drop (i32.const 1))
(drop (i32.const 1))
(drop (i32.const 1))
;; return_call executes the call after returning from this function.
;; This try cannot catch exceptions it throws, so we can fold it out of
;; the try.
(return_call $foo-i32)
)
(catch_all
(drop (i32.const 1))
(drop (i32.const 1))
(drop (i32.const 1))
(return_call $foo-i32)
)
)
(i32.const 0)
)
;; CHECK: (func $try-call-optimize-expression-tails-success (type $1)
;; CHECK-NEXT: (block $x
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (br $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (br $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $try-call-optimize-expression-tails-success
(block $x
(try
(do
;; Expressions that cannot throw can be taken out of 'try' scope.
(drop (i32.const 1))
(drop (i32.const 1))
(drop (i32.const 1))
(br $x)
)
(catch_all
(drop (i32.const 1))
(drop (i32.const 1))
(drop (i32.const 1))
(br $x)
)
)
(unreachable)
)
)
;; CHECK: (func $try-call-optimize-expression-tails (type $1)
;; CHECK-NEXT: (block $x
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (br $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch_all
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: (br $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $try-call-optimize-expression-tails
(block $x
(try
(do
;; Expressions that can throw should NOT be taken out of 'try' scope.
(call $foo)
(call $foo)
(call $foo)
(br $x)
)
(catch_all
(call $foo)
(call $foo)
(call $foo)
(br $x)
)
)
(unreachable)
)
)
;; CHECK: (func $if-arms-in-catch (type $0) (result i32)
;; CHECK-NEXT: (local $0 i32)
;; CHECK-NEXT: (try
;; CHECK-NEXT: (do
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: (catch $e-i32
;; CHECK-NEXT: (local.set $0
;; CHECK-NEXT: (pop i32)
;; CHECK-NEXT: )
;; CHECK-NEXT: (block
;; CHECK-NEXT: (block
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (local.get $0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (i32.const 1)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-arms-in-catch (result i32)
(try
(do
(unreachable)
)
(catch $e-i32
;; These if arms can be folded, after which the if is replaced by a
;; block, so we need a fixup for the pop.
(if
(pop i32)
(then
(drop
(i32.eqz
(i32.const 1)
)
)
)
(else
(drop
(i32.eqz
(i32.const 1)
)
)
)
)
(unreachable)
)
)
)
)