summaryrefslogtreecommitdiff
path: root/test/lit
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit')
-rw-r--r--test/lit/passes/dce_all-features.wast1417
-rw-r--r--test/lit/passes/dce_vacuum_remove-unused-names.wast82
-rw-r--r--test/lit/passes/dealign.wast48
-rw-r--r--test/lit/passes/dealign64.wast48
-rw-r--r--test/lit/passes/denan.wast271
-rw-r--r--test/lit/passes/directize_all-features.wast521
6 files changed, 2387 insertions, 0 deletions
diff --git a/test/lit/passes/dce_all-features.wast b/test/lit/passes/dce_all-features.wast
new file mode 100644
index 000000000..58bdbf5e5
--- /dev/null
+++ b/test/lit/passes/dce_all-features.wast
@@ -0,0 +1,1417 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_test.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --dce --all-features -S -o - | filecheck %s
+
+(module
+ (memory 10)
+ ;; CHECK: (type $none_=>_i32 (func (result i32)))
+
+ ;; CHECK: (type $1 (func))
+
+ ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32)))
+
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ (type $1 (func))
+ (table 1 1 funcref)
+ (elem (i32.const 0) $call-me)
+ ;; CHECK: (type $i64_i64_=>_i64 (func (param i64 i64) (result i64)))
+
+ ;; CHECK: (type $f32_i64_=>_none (func (param f32 i64)))
+
+ ;; CHECK: (type $f32_i64_=>_i32 (func (param f32 i64) (result i32)))
+
+ ;; CHECK: (global $x (mut i32) (i32.const 0))
+ (global $x (mut i32) (i32.const 0))
+ ;; CHECK: (memory $0 10)
+
+ ;; CHECK: (table $0 1 1 funcref)
+
+ ;; CHECK: (elem (i32.const 0) $call-me)
+
+ ;; CHECK: (func $call-me (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $call-me (type $ii) (param $0 i32) (param $1 i32)
+ (nop)
+ )
+ ;; CHECK: (func $code-to-kill
+ ;; CHECK-NEXT: (local $x i32)
+ ;; CHECK-NEXT: (block $out
+ ;; CHECK-NEXT: (br $out)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (block $out3
+ ;; CHECK-NEXT: (return)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $out4
+ ;; CHECK-NEXT: (br_table $out4 $out4 $out4 $out4
+ ;; CHECK-NEXT: (i32.const 4)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $out5
+ ;; CHECK-NEXT: (br_if $out5
+ ;; CHECK-NEXT: (i32.const 3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (block $block4
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $out16
+ ;; CHECK-NEXT: (block $in
+ ;; CHECK-NEXT: (br_if $out16
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (block $block11
+ ;; CHECK-NEXT: (block $out18
+ ;; CHECK-NEXT: (block $in19
+ ;; CHECK-NEXT: (br_if $in19
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $out20
+ ;; CHECK-NEXT: (block $in21
+ ;; CHECK-NEXT: (br_table $out20 $in21
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $out22
+ ;; CHECK-NEXT: (block $in23
+ ;; CHECK-NEXT: (br_table $in23 $out22
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (block $block13
+ ;; CHECK-NEXT: (block $out25
+ ;; CHECK-NEXT: (block $in26
+ ;; CHECK-NEXT: (br_table $in26 $in26
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (block $block15
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 10)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $out29
+ ;; CHECK-NEXT: (loop $in30
+ ;; CHECK-NEXT: (br_if $out29
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (block $block20
+ ;; CHECK-NEXT: (loop $in32
+ ;; CHECK-NEXT: (br_if $in32
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 123)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 3)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const -1)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 123)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 456)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const -2)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 139)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const -3)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 246)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const -4)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 11)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 22)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 33)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 44)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 55)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 66)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 77)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 88)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 99)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 100)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 123)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 456)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 101)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 123)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 102)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1337)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $code-to-kill (type $1)
+ (local $x i32)
+ (block $out
+ (br $out)
+ (drop
+ (i32.const 0)
+ )
+ (if
+ (i32.const 1)
+ (drop
+ (i32.const 2)
+ )
+ )
+ (br_table $out $out $out $out
+ (i32.const 3)
+ )
+ (call $code-to-kill)
+ )
+ (if
+ (i32.const 0)
+ (block $out
+ (unreachable)
+ (drop
+ (i32.const 0)
+ )
+ )
+ )
+ (if
+ (i32.const 0)
+ (block $out
+ (return)
+ (drop
+ (i32.const 0)
+ )
+ )
+ )
+ (block $out
+ (br_table $out $out $out $out
+ (i32.const 4)
+ )
+ (drop
+ (i32.const 0)
+ )
+ )
+ (block $out
+ (br_if $out
+ (i32.const 3)
+ )
+ (drop
+ (i32.const 0)
+ )
+ )
+ (if
+ (i32.const 0)
+ (block $block4
+ (if
+ (i32.const 0)
+ (block $out
+ (unreachable)
+ (drop
+ (i32.const 0)
+ )
+ )
+ (block $out
+ (unreachable)
+ (drop
+ (i32.const 0)
+ )
+ )
+ )
+ (drop
+ (i32.const 0)
+ )
+ )
+ )
+ (if
+ (i32.const 0)
+ (drop
+ (block $out (result i32)
+ (br $out
+ (unreachable)
+ )
+ (drop
+ (i32.const 0)
+ )
+ (unreachable)
+ )
+ )
+ )
+ (if
+ (i32.const 0)
+ (drop
+ (block $out (result i32)
+ (br_if $out
+ (unreachable)
+ (i32.const 0)
+ )
+ (drop
+ (i32.const 0)
+ )
+ (unreachable)
+ )
+ )
+ )
+ (if
+ (i32.const 0)
+ (drop
+ (block $out (result i32)
+ (br_if $out
+ (unreachable)
+ (unreachable)
+ )
+ (drop
+ (i32.const 0)
+ )
+ (unreachable)
+ )
+ )
+ )
+ (block $out
+ (block $in
+ (br_if $out
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.const 0)
+ (block $block11
+ (block $out
+ (block $in
+ (br_if $in
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (drop
+ (i32.const 10)
+ )
+ )
+ )
+ (block $out
+ (block $in
+ (br_table $out $in
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (block $out
+ (block $in
+ (br_table $in $out
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.const 0)
+ (block $block13
+ (block $out
+ (block $in
+ (br_table $in $in
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (drop
+ (i32.const 10)
+ )
+ )
+ )
+ (if
+ (i32.const 0)
+ (block $block15
+ (drop
+ (i32.const 10)
+ )
+ (drop
+ (i32.const 42)
+ )
+ (unreachable)
+ (return
+ (unreachable)
+ )
+ (unreachable)
+ (return)
+ )
+ )
+ (if
+ (i32.const 0)
+ (loop $loop-in18
+ (unreachable)
+ )
+ )
+ (block $out
+ (loop $in
+ (br_if $out
+ (i32.const 1)
+ )
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const 0)
+ (block $block20
+ (loop $in
+ (br_if $in
+ (i32.const 1)
+ )
+ (unreachable)
+ )
+ (drop
+ (i32.const 10)
+ )
+ )
+ )
+ (if
+ (i32.const 1)
+ (call $call-me
+ (i32.const 123)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const 2)
+ (call $call-me
+ (unreachable)
+ (i32.const 0)
+ )
+ )
+ (if
+ (i32.const 3)
+ (call $call-me
+ (unreachable)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const -1)
+ (call_indirect (type $ii)
+ (i32.const 123)
+ (i32.const 456)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const -2)
+ (call_indirect (type $ii)
+ (i32.const 139)
+ (unreachable)
+ (i32.const 0)
+ )
+ )
+ (if
+ (i32.const -3)
+ (call_indirect (type $ii)
+ (i32.const 246)
+ (unreachable)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const -4)
+ (call_indirect (type $ii)
+ (unreachable)
+ (unreachable)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const 11)
+ (local.set $x
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const 22)
+ (drop
+ (i32.load
+ (unreachable)
+ )
+ )
+ )
+ (if
+ (i32.const 33)
+ (i32.store
+ (i32.const 0)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const 44)
+ (i32.store
+ (unreachable)
+ (i32.const 0)
+ )
+ )
+ (if
+ (i32.const 55)
+ (i32.store
+ (unreachable)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const 66)
+ (drop
+ (i32.eqz
+ (unreachable)
+ )
+ )
+ )
+ (if
+ (i32.const 77)
+ (drop
+ (i32.add
+ (unreachable)
+ (i32.const 0)
+ )
+ )
+ )
+ (if
+ (i32.const 88)
+ (drop
+ (i32.add
+ (i32.const 0)
+ (unreachable)
+ )
+ )
+ )
+ (if
+ (i32.const 99)
+ (i32.add
+ (unreachable)
+ (unreachable)
+ )
+ )
+ (if
+ (i32.const 100)
+ (drop
+ (select
+ (i32.const 123)
+ (i32.const 456)
+ (unreachable)
+ )
+ )
+ )
+ (if
+ (i32.const 101)
+ (drop
+ (select
+ (i32.const 123)
+ (unreachable)
+ (i32.const 456)
+ )
+ )
+ )
+ (if
+ (i32.const 102)
+ (drop
+ (select
+ (unreachable)
+ (i32.const 123)
+ (i32.const 456)
+ )
+ )
+ )
+ (drop
+ (i32.const 1337)
+ )
+ )
+ ;; CHECK: (func $killer
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $killer (type $1)
+ (unreachable)
+ (drop
+ (i32.const 1000)
+ )
+ )
+ ;; CHECK: (func $target
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 2000)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $target (type $1)
+ (drop
+ (i32.const 2000)
+ )
+ )
+ ;; CHECK: (func $typed-block-none-then-unreachable (result i32)
+ ;; CHECK-NEXT: (block $top-typed
+ ;; CHECK-NEXT: (block $switch$0
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $typed-block-none-then-unreachable (result i32)
+ (block $top-typed (result i32)
+ (block $switch$0 ;; this looks like it can be broken to, so it gets type 'none'
+ (return
+ (i32.const 0)
+ )
+ (br $switch$0) ;; this is not reachable, so dce cleans it up, changing $switch$0's type
+ )
+ (return ;; and this is cleaned up as well, leaving $top-typed in need of a type change
+ (i32.const 1)
+ )
+ )
+ )
+ ;; CHECK: (func $typed-block-remove-br-changes-type (param $$$0 i32) (result i32)
+ ;; CHECK-NEXT: (block $switch$7
+ ;; CHECK-NEXT: (block $switch-default$10
+ ;; CHECK-NEXT: (block $switch-case$9
+ ;; CHECK-NEXT: (block $switch-case$8
+ ;; CHECK-NEXT: (br_table $switch-case$9 $switch-case$8 $switch-default$10
+ ;; CHECK-NEXT: (i32.const -1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (local.get $$$0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (local.get $$$0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $typed-block-remove-br-changes-type (param $$$0 i32) (result i32)
+ (block $switch$7
+ (block $switch-default$10
+ (block $switch-case$9
+ (block $switch-case$8
+ (br_table $switch-case$9 $switch-case$8 $switch-default$10
+ (i32.const -1)
+ )
+ )
+ )
+ (return
+ (local.get $$$0)
+ )
+ (br $switch$7)
+ )
+ (return
+ (local.get $$$0)
+ )
+ )
+ (return
+ (i32.const 0)
+ )
+ )
+ ;; CHECK: (func $global
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $global
+ (unreachable)
+ (drop (global.get $x))
+ (global.set $x (i32.const 1))
+ )
+ ;; CHECK: (func $ret (result i32)
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $ret (result i32)
+ (return
+ (i32.const 0)
+ )
+ (nop)
+ (i32.const 0)
+ )
+ ;; CHECK: (func $unreachable-br (result i32)
+ ;; CHECK-NEXT: (block $out (result i32)
+ ;; CHECK-NEXT: (br $out
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-br (result i32)
+ (block $out (result i32)
+ (br $out
+ (br $out (i32.const 0))
+ )
+ )
+ )
+ ;; CHECK: (func $unreachable-br-loop (result i32)
+ ;; CHECK-NEXT: (loop $out
+ ;; CHECK-NEXT: (br $out)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-br-loop (result i32)
+ (loop $out
+ (br $out)
+ )
+ )
+ ;; CHECK: (func $unreachable-block-ends-switch (result i32)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (block $label$3
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-block-ends-switch (result i32)
+ (block $label$0 (result i32)
+ (block $label$3
+ (nop)
+ (br_table $label$3
+ (unreachable)
+ )
+ (unreachable)
+ )
+ (i32.const 19)
+ )
+ )
+ ;; CHECK: (func $unreachable-block-ends-br_if (result i32)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (block $label$2
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-block-ends-br_if (result i32)
+ (block $label$0 (result i32)
+ (block $label$2
+ (nop)
+ (br_if $label$2
+ (unreachable)
+ )
+ (unreachable)
+ )
+ (i32.const 19)
+ )
+ )
+ ;; CHECK: (func $unreachable-brs-3 (result i32)
+ ;; CHECK-NEXT: (block $label$0 (result i32)
+ ;; CHECK-NEXT: (br $label$0
+ ;; CHECK-NEXT: (i32.const 18)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-brs-3 (result i32)
+ (block $label$0 (result i32)
+ (br $label$0
+ (memory.grow
+ (br $label$0
+ (i32.const 18)
+ )
+ )
+ )
+ (i32.const 21)
+ )
+ )
+ ;; CHECK: (func $unreachable-brs-4 (param $var$0 i32) (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (block $label$1
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.const 4104)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-brs-4 (param $var$0 i32) (result i32)
+ (i32.add
+ (i32.const 1)
+ (block $label$0 (result i32)
+ (br $label$0
+ (block $label$1 (result i32) ;; this block is declared i32, but we can see it is unreachable
+ (drop
+ (br_if $label$0
+ (i32.const 4104)
+ (unreachable)
+ )
+ )
+ (i32.const 4)
+ )
+ )
+ (i32.const 16)
+ )
+ )
+ )
+ ;; CHECK: (func $call-unreach (param $var$0 i64) (param $var$1 i64) (result i64)
+ ;; CHECK-NEXT: (local $2 i64)
+ ;; CHECK-NEXT: (if (result i64)
+ ;; CHECK-NEXT: (i64.eqz
+ ;; CHECK-NEXT: (local.get $var$0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $label$0 (result i64)
+ ;; CHECK-NEXT: (local.get $var$1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $label$1
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i64.sub
+ ;; CHECK-NEXT: (local.get $var$0)
+ ;; CHECK-NEXT: (i64.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block $block (result i64)
+ ;; CHECK-NEXT: (local.set $2
+ ;; CHECK-NEXT: (local.get $var$0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (local.get $2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $call-unreach (param $var$0 i64) (param $var$1 i64) (result i64)
+ (local $2 i64)
+ (if (result i64)
+ (i64.eqz
+ (local.get $var$0)
+ )
+ (block $label$0 (result i64)
+ (local.get $var$1)
+ )
+ (block $label$1 (result i64)
+ (call $call-unreach
+ (i64.sub
+ (local.get $var$0)
+ (i64.const 1)
+ )
+ (i64.mul
+ (block (result i64)
+ (local.set $2
+ (local.get $var$0)
+ )
+ (nop)
+ (local.get $2)
+ )
+ (unreachable)
+ )
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $br-gone-means-block-type-changes-then-refinalize-at-end-is-too-late (param $var$0 i32) (result i32)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (block $block
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $br-gone-means-block-type-changes-then-refinalize-at-end-is-too-late (param $var$0 i32) (result i32)
+ (block $label$0 (result i32)
+ (br $label$0
+ (block (result i32)
+ (nop)
+ (drop
+ (br_if $label$0
+ (unreachable)
+ (local.get $var$0)
+ )
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $br-with-unreachable-value-should-not-give-a-block-a-value (param $var$0 i32) (result i32)
+ ;; CHECK-NEXT: (block $label$0 (result i32)
+ ;; CHECK-NEXT: (block $block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (br_if $label$0
+ ;; CHECK-NEXT: (i32.const 8)
+ ;; CHECK-NEXT: (local.get $var$0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $br-with-unreachable-value-should-not-give-a-block-a-value (param $var$0 i32) (result i32)
+ (block $label$0 (result i32)
+ (br $label$0
+ (block (result i32) ;; turns into unreachable when refinalized
+ (drop
+ (br_if $label$0
+ (i32.const 8)
+ (local.get $var$0)
+ )
+ )
+ (unreachable)
+ )
+ )
+ (i32.const 16)
+ )
+ )
+ ;; CHECK: (func $replace-br-value-of-i32-with-unreachable (result i32)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (block $label$1
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $replace-br-value-of-i32-with-unreachable (result i32)
+ (block $label$0 (result i32)
+ (br $label$0
+ (block $label$1 (result i32)
+ (nop)
+ (unreachable)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $shorten-block-requires-sync-refinalize (param $var$0 i32) (param $var$1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $shorten-block-requires-sync-refinalize (param $var$0 i32) (param $var$1 i32)
+ (block $label$0
+ (unreachable)
+ (if
+ (unreachable)
+ (br_if $label$0
+ (local.get $var$1)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $block-with-type-but-is-unreachable (param $var$0 i32) (result i32)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (block $block
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $block-with-type-but-is-unreachable (param $var$0 i32) (result i32)
+ (block $label$0 (result i32)
+ (br $label$0
+ (block $block (result i32)
+ (nop)
+ (unreachable)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $if-with-type-but-is-unreachable (param $var$0 i32) (result i32)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (local.get $var$0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $if-with-type-but-is-unreachable (param $var$0 i32) (result i32)
+ (block $label$0 (result i32)
+ (br $label$0
+ (if (result i32)
+ (local.get $var$0)
+ (unreachable)
+ (unreachable)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $unreachable-loop
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $unreachable-loop
+ (loop $label$2
+ (unreachable)
+ (br $label$2)
+ )
+ )
+ ;; CHECK: (func $br-block-from-unary (result i32)
+ ;; CHECK-NEXT: (block $label$6 (result i32)
+ ;; CHECK-NEXT: (block $label$7
+ ;; CHECK-NEXT: (br $label$6
+ ;; CHECK-NEXT: (i32.const 8)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $br-block-from-unary (result i32)
+ (block $label$6 (result i32)
+ (i32.ctz
+ (block $label$7 (result i32)
+ (br $label$6
+ (i32.const 8)
+ )
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $replace-unary-with-br-child
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block $label$6 (result i32)
+ ;; CHECK-NEXT: (br $label$6
+ ;; CHECK-NEXT: (i32.const 8)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $replace-unary-with-br-child
+ (drop
+ (block $label$6 (result i32)
+ (i32.ctz
+ (br $label$6
+ (i32.const 8)
+ )
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $br_if-unreach-then-br_if-normal
+ ;; CHECK-NEXT: (block $out
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $br_if-unreach-then-br_if-normal
+ (block $out
+ (nop)
+ (br_if $out
+ (unreachable)
+ )
+ (br_if $out
+ (i32.const 1)
+ )
+ )
+ )
+ ;; CHECK: (func $replace-with-unreachable-affects-parent (param $var$0 f32) (param $var$1 i64)
+ ;; CHECK-NEXT: (block $top
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i64.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (block $block (result i32)
+ ;; CHECK-NEXT: (call $replace-with-unreachable-affects-parent
+ ;; CHECK-NEXT: (f32.const 1)
+ ;; CHECK-NEXT: (i64.const -15917430362925035)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $replace-with-unreachable-affects-parent (param $var$0 f32) (param $var$1 i64)
+ (block $top
+ (drop
+ (f32.load offset=4
+ (i64.ne
+ (i64.const 0)
+ (if (result i64)
+ (block (result i32)
+ (call $replace-with-unreachable-affects-parent
+ (f32.const 1)
+ (i64.const -15917430362925035)
+ )
+ (i32.const 1)
+ )
+ (unreachable)
+ (unreachable)
+ )
+ )
+ )
+ )
+ (nop) ;; this is not reachable due to the above code, so we replace it with unreachable. type should go to parent
+ )
+ )
+ ;; CHECK: (func $replace-block-changes-later-when-if-goes
+ ;; CHECK-NEXT: (block $top
+ ;; CHECK-NEXT: (global.set $x
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block $inner
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $helper
+ ;; CHECK-NEXT: (f32.const 1)
+ ;; CHECK-NEXT: (i64.const -15917430362925035)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $replace-block-changes-later-when-if-goes
+ (block $top ;; and so should this
+ (global.set $x
+ (i32.const 0)
+ )
+ (drop
+ (f32.load offset=4
+ (i64.ne
+ (block $inner (result i64) ;; this becomes unreachable
+ (drop
+ (call $helper
+ (f32.const 1)
+ (i64.const -15917430362925035)
+ )
+ )
+ (unreachable)
+ )
+ (i64.const 0)
+ )
+ )
+ )
+ (if
+ (i32.load16_s offset=22 align=1
+ (i32.const 0)
+ )
+ (br $top) ;; this keeps the block none after the inner block gets unreachable. but it will vanish into unreachable itself
+ (unreachable)
+ )
+ )
+ )
+ ;; CHECK: (func $helper (param $var$0 f32) (param $var$1 i64) (result i32)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ (func $helper (param $var$0 f32) (param $var$1 i64) (result i32)
+ (i32.const 0)
+ )
+)
+;; if goes to unreachable, need to propagate that up to the global.set
+(module
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (global $global (mut f64) (f64.const 0))
+ (global $global (mut f64) (f64.const 0))
+ ;; CHECK: (func $0
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $0
+ (global.set $global
+ (if (result f64)
+ (i32.const 0)
+ (unreachable)
+ (unreachable)
+ )
+ )
+ )
+)
+(module
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (func $0
+ ;; CHECK-NEXT: (local $local f64)
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $0
+ (local $local f64)
+ (local.set $local
+ (if (result f64)
+ (i32.const 0)
+ (unreachable)
+ (unreachable)
+ )
+ )
+ )
+)
+
+(module
+ ;; CHECK: (type $none_=>_i32 (func (result i32)))
+
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (func $unnecessary-concrete-block (result i32)
+ ;; CHECK-NEXT: (block $foo
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unnecessary-concrete-block (result i32)
+ (block $foo (result i32) ;; unnecessary type
+ (nop)
+ (unreachable)
+ )
+ )
+ ;; CHECK: (func $necessary-concrete-block (result i32)
+ ;; CHECK-NEXT: (block $foo (result i32)
+ ;; CHECK-NEXT: (br $foo
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $necessary-concrete-block (result i32)
+ (block $foo (result i32)
+ (br $foo (i32.const 1))
+ (unreachable)
+ )
+ )
+ ;; CHECK: (func $unnecessary-concrete-if (result i32)
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unnecessary-concrete-if (result i32)
+ (if (result i32) ;; unnecessary type
+ (i32.const 0)
+ (return (i32.const 1))
+ (unreachable)
+ )
+ )
+ ;; CHECK: (func $unnecessary-concrete-try (result i32)
+ ;; CHECK-NEXT: (try $try
+ ;; CHECK-NEXT: (do
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (catch_all
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unnecessary-concrete-try (result i32)
+ (try (result i32)
+ (do
+ (unreachable)
+ )
+ (catch_all
+ (unreachable)
+ )
+ )
+ )
+ ;; CHECK: (func $note-loss-of-if-children
+ ;; CHECK-NEXT: (block $label$1
+ ;; CHECK-NEXT: (block $label$2
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $note-loss-of-if-children
+ (block $label$1
+ (if ;; begins unreachable - type never changes - but after the condition
+ ;; becomes unreachable, it will lose the children, which means no more
+ ;; br to the outer block, changing that type.
+ (block $label$2 (result i32)
+ (nop)
+ (unreachable)
+ )
+ (unreachable)
+ (br $label$1)
+ )
+ )
+ )
+ ;; CHECK: (func $note-loss-of-non-control-flow-children
+ ;; CHECK-NEXT: (block $out
+ ;; CHECK-NEXT: (block $block
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $note-loss-of-non-control-flow-children
+ (block $out
+ (drop
+ (i32.add
+ (block (result i32)
+ (nop)
+ (unreachable)
+ )
+ (br $out) ;; when this is removed as dead, the block becomes unreachable
+ )
+ )
+ )
+ )
+)
+(module
+ ;; CHECK: (type $none_=>_ref|any| (func (result (ref any))))
+
+ ;; CHECK: (func $foo (result (ref any))
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (result (ref any))
+ (block $label$1 (result (ref any))
+ ;; this break has an unreachable input, and so it does not have a heap type
+ ;; there, and no heap type to send on the branch. this tests we do not hit
+ ;; the assertion in getHeapType() if we call that.
+ (br_on_non_null $label$1
+ (block (result anyref)
+ (unreachable)
+ )
+ )
+ (unreachable)
+ )
+ )
+)
diff --git a/test/lit/passes/dce_vacuum_remove-unused-names.wast b/test/lit/passes/dce_vacuum_remove-unused-names.wast
new file mode 100644
index 000000000..13d0800db
--- /dev/null
+++ b/test/lit/passes/dce_vacuum_remove-unused-names.wast
@@ -0,0 +1,82 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_test.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --dce --vacuum --remove-unused-names -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (type $none_=>_i32 (func (result i32)))
+
+ ;; CHECK: (type $f32_f32_=>_f32 (func (param f32 f32) (result f32)))
+
+ ;; CHECK: (type $i64_=>_i64 (func (param i64) (result i64)))
+
+ ;; CHECK: (func $__Z12serveroptionPc (result i32)
+ ;; CHECK-NEXT: (return
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $__Z12serveroptionPc (result i32)
+ (block $switch$0
+ (return
+ (i32.const 0)
+ )
+ (br $switch$0)
+ )
+ (return
+ (i32.const 0)
+ )
+ )
+ ;; CHECK: (func $drop-unreachable (param $var$0 f32) (param $var$1 f32) (result f32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $drop-unreachable (param $var$0 f32) (param $var$1 f32) (result f32)
+ (block $label$0 (result f32)
+ (loop $label$2
+ (drop
+ (unreachable)
+ )
+ (unreachable)
+ )
+ (local.get $var$1)
+ )
+ )
+
+ ;; CHECK: (func $set-unreachable (param $var$0 i64) (result i64)
+ ;; CHECK-NEXT: (local $var$1 i64)
+ ;; CHECK-NEXT: (local $var$2 i64)
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i64.eq
+ ;; CHECK-NEXT: (local.get $var$1)
+ ;; CHECK-NEXT: (i64.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $set-unreachable (param $var$0 i64) (result i64)
+ (local $var$1 i64)
+ (local $var$2 i64)
+ (block $label$0 (result i64)
+ (block $label$1
+ (loop $label$2
+ (if
+ (i64.eq
+ (local.get $var$1)
+ (i64.const 0)
+ )
+ (unreachable)
+ (local.set $var$2
+ (i64.mul
+ (unreachable)
+ (local.get $var$2)
+ )
+ )
+ )
+ (br $label$2)
+ )
+ )
+ (local.get $var$2)
+ )
+ )
+)
+
diff --git a/test/lit/passes/dealign.wast b/test/lit/passes/dealign.wast
new file mode 100644
index 000000000..7af89659b
--- /dev/null
+++ b/test/lit/passes/dealign.wast
@@ -0,0 +1,48 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_test.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --dealign -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (memory $0 1 1)
+ (memory $0 1 1)
+ ;; CHECK: (func $test
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.load align=1
+ ;; CHECK-NEXT: (i32.const 4)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.load align=1
+ ;; CHECK-NEXT: (i32.const 8)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.load align=1
+ ;; CHECK-NEXT: (i32.const 12)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.store align=1
+ ;; CHECK-NEXT: (i32.const 16)
+ ;; CHECK-NEXT: (i32.const 28)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.store align=1
+ ;; CHECK-NEXT: (i32.const 20)
+ ;; CHECK-NEXT: (i32.const 32)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.store align=1
+ ;; CHECK-NEXT: (i32.const 24)
+ ;; CHECK-NEXT: (i32.const 36)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test
+ (drop (i32.load (i32.const 4)))
+ (drop (i32.load align=1 (i32.const 8)))
+ (drop (i32.load align=2 (i32.const 12)))
+ (i32.store (i32.const 16) (i32.const 28))
+ (i32.store align=1 (i32.const 20) (i32.const 32))
+ (i32.store align=2 (i32.const 24) (i32.const 36))
+ )
+)
diff --git a/test/lit/passes/dealign64.wast b/test/lit/passes/dealign64.wast
new file mode 100644
index 000000000..28f80dafa
--- /dev/null
+++ b/test/lit/passes/dealign64.wast
@@ -0,0 +1,48 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_test.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --dealign --enable-memory64 -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (memory $0 i64 1 1)
+ (memory $0 i64 1 1)
+ ;; CHECK: (func $test
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.load align=1
+ ;; CHECK-NEXT: (i64.const 4)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.load align=1
+ ;; CHECK-NEXT: (i64.const 8)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i32.load align=1
+ ;; CHECK-NEXT: (i64.const 12)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.store align=1
+ ;; CHECK-NEXT: (i64.const 16)
+ ;; CHECK-NEXT: (i32.const 28)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.store align=1
+ ;; CHECK-NEXT: (i64.const 20)
+ ;; CHECK-NEXT: (i32.const 32)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.store align=1
+ ;; CHECK-NEXT: (i64.const 24)
+ ;; CHECK-NEXT: (i32.const 36)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test
+ (drop (i32.load (i64.const 4)))
+ (drop (i32.load align=1 (i64.const 8)))
+ (drop (i32.load align=2 (i64.const 12)))
+ (i32.store (i64.const 16) (i32.const 28))
+ (i32.store align=1 (i64.const 20) (i32.const 32))
+ (i32.store align=2 (i64.const 24) (i32.const 36))
+ )
+)
diff --git a/test/lit/passes/denan.wast b/test/lit/passes/denan.wast
new file mode 100644
index 000000000..a808df4b0
--- /dev/null
+++ b/test/lit/passes/denan.wast
@@ -0,0 +1,271 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_test.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --denan -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (type $f32_=>_f32 (func (param f32) (result f32)))
+
+ ;; CHECK: (type $f64_=>_f64 (func (param f64) (result f64)))
+
+ ;; CHECK: (type $i32_f32_i64_f64_=>_none (func (param i32 f32 i64 f64)))
+
+ ;; CHECK: (type $f32_f64_=>_none (func (param f32 f64)))
+
+ ;; CHECK: (global $global$1 (mut f32) (f32.const 0))
+ (global $global$1 (mut f32) (f32.const nan))
+ ;; CHECK: (global $global$2 (mut f32) (f32.const 12.34000015258789))
+ (global $global$2 (mut f32) (f32.const 12.34))
+ ;; CHECK: (func $foo32 (param $x f32) (result f32)
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (call $foo32
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo32 (param $x f32) (result f32)
+ (call $foo32 (local.get $x))
+ )
+ ;; CHECK: (func $foo64 (param $x f64) (result f64)
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (call $deNan64
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $deNan64
+ ;; CHECK-NEXT: (call $foo64
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo64 (param $x f64) (result f64)
+ (call $foo64 (local.get $x))
+ )
+ ;; CHECK: (func $various (param $x i32) (param $y f32) (param $z i64) (param $w f64)
+ ;; CHECK-NEXT: (local.set $y
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $w
+ ;; CHECK-NEXT: (call $deNan64
+ ;; CHECK-NEXT: (local.get $w)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $various (param $x i32) (param $y f32) (param $z i64) (param $w f64)
+ )
+ ;; CHECK: (func $ignore-local.get (param $f f32) (param $d f64)
+ ;; CHECK-NEXT: (local.set $f
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $d
+ ;; CHECK-NEXT: (call $deNan64
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $f
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $d
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (f32.abs
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $deNan64
+ ;; CHECK-NEXT: (f64.abs
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $f
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (f32.abs
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $d
+ ;; CHECK-NEXT: (call $deNan64
+ ;; CHECK-NEXT: (f64.abs
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $f)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $ignore-local.get (param $f f32) (param $d f64)
+ (drop (local.get $f))
+ (drop (local.get $d))
+ (local.set $f (local.get $f))
+ (local.set $d (local.get $d))
+ (drop (local.get $f))
+ (drop (local.get $d))
+ (drop (f32.abs (local.get $f)))
+ (drop (f64.abs (local.get $d)))
+ (local.set $f (f32.abs (local.get $f)))
+ (local.set $d (f64.abs (local.get $d)))
+ (drop (local.get $f))
+ (drop (local.get $d))
+ )
+ ;; CHECK: (func $tees (param $x f32) (result f32)
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.tee $x
+ ;; CHECK-NEXT: (local.tee $x
+ ;; CHECK-NEXT: (local.tee $x
+ ;; CHECK-NEXT: (local.tee $x
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $tees (param $x f32) (result f32)
+ (local.tee $x
+ (local.tee $x
+ (local.tee $x
+ (local.tee $x
+ (local.get $x))))))
+ ;; CHECK: (func $select (param $x f32) (result f32)
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (call $deNan32
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (select
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $select (param $x f32) (result f32)
+ (select
+ (local.get $x)
+ (local.get $x)
+ (i32.const 1)))
+)
+;; existing names should not be a problem
+;; CHECK: (func $deNan32 (param $0 f32) (result f32)
+;; CHECK-NEXT: (if (result f32)
+;; CHECK-NEXT: (f32.eq
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (f32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $deNan64 (param $0 f64) (result f64)
+;; CHECK-NEXT: (if (result f64)
+;; CHECK-NEXT: (f64.eq
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (f64.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+(module
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (type $f32_=>_f32 (func (param f32) (result f32)))
+
+ ;; CHECK: (type $f64_=>_f64 (func (param f64) (result f64)))
+
+ ;; CHECK: (func $deNan32
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $deNan32)
+ ;; CHECK: (func $deNan64
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $deNan64)
+ ;; CHECK: (func $foo32 (param $x f32) (result f32)
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (call $deNan32_0
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $deNan32_0
+ ;; CHECK-NEXT: (call $foo32
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo32 (param $x f32) (result f32)
+ (call $foo32 (local.get $x))
+ )
+ ;; CHECK: (func $foo64 (param $x f64) (result f64)
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (call $deNan64_0
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $deNan64_0
+ ;; CHECK-NEXT: (call $foo64
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo64 (param $x f64) (result f64)
+ (call $foo64 (local.get $x))
+ )
+
+)
+;; CHECK: (func $deNan32_0 (param $0 f32) (result f32)
+;; CHECK-NEXT: (if (result f32)
+;; CHECK-NEXT: (f32.eq
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (f32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+
+;; CHECK: (func $deNan64_0 (param $0 f64) (result f64)
+;; CHECK-NEXT: (if (result f64)
+;; CHECK-NEXT: (f64.eq
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: (f64.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
diff --git a/test/lit/passes/directize_all-features.wast b/test/lit/passes/directize_all-features.wast
new file mode 100644
index 000000000..d9010a76d
--- /dev/null
+++ b/test/lit/passes/directize_all-features.wast
@@ -0,0 +1,521 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_test.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --directize --all-features -S -o - | filecheck %s
+
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call $foo
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32)))
+
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ ;; CHECK: (table $1 5 5 funcref)
+ (table $1 5 5 funcref)
+ (elem (table $0) (i32.const 1) func $dummy)
+ (elem (table $1) (i32.const 1) func $f)
+ ;; CHECK: (elem $0 (table $0) (i32.const 1) func $dummy)
+
+ ;; CHECK: (elem $1 (table $1) (i32.const 1) func $f)
+
+ ;; CHECK: (func $dummy (param $0 i32) (result i32)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ (func $dummy (param i32) (result i32)
+ (local.get 0)
+ )
+ ;; CHECK: (func $f (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $f (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $g (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call $f
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $g (param $x i32) (param $y i32)
+ (call_indirect $1 (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+;; at table edges
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ ;; CHECK: (table $1 5 5 funcref)
+ (table $1 5 5 funcref)
+ (elem (table $1) (i32.const 4) func $foo)
+ ;; CHECK: (elem (table $1) (i32.const 4) func $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call $foo
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect $1 (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 4)
+ )
+ )
+)
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (elem (i32.const 0) $foo)
+ ;; CHECK: (elem (i32.const 0) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call $foo
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 0)
+ )
+ )
+)
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ ;; CHECK: (table $1 5 5 funcref)
+ (table $1 5 5 funcref)
+ (elem (i32.const 0) $foo $foo $foo $foo $foo)
+ (elem (table $1) (i32.const 0) func $foo $foo $foo $foo $foo)
+ ;; CHECK: (elem $0 (table $0) (i32.const 0) func $foo $foo $foo $foo $foo)
+
+ ;; CHECK: (elem $1 (table $1) (i32.const 0) func $foo $foo $foo $foo $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call $foo
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect $1 (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 2)
+ )
+ )
+)
+;; imported table
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (import "env" "table" (table $table 5 5 funcref))
+ (import "env" "table" (table $table 5 5 funcref))
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call_indirect $table (type $ii)
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+;; exported table
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (export "tab" (table $0))
+ (export "tab" (table $0))
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call_indirect $0 (type $ii)
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+;; non-constant table offset
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (global $g (mut i32) (i32.const 1))
+
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (global $g (mut i32) (i32.const 1))
+ (elem (global.get $g) $foo)
+ ;; CHECK: (elem (global.get $g) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call_indirect $0 (type $ii)
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (global $g (mut i32) (i32.const 1))
+
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ ;; CHECK: (table $1 5 5 funcref)
+ (table $1 5 5 funcref)
+ (global $g (mut i32) (i32.const 1))
+ (elem (table $1) (global.get $g) func $foo)
+ ;; CHECK: (elem (table $1) (global.get $g) func $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call_indirect $1 (type $ii)
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect $1 (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+;; non-constant call index
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))
+
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32) (param $z i32)
+ ;; CHECK-NEXT: (call_indirect $0 (type $ii)
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: (local.get $z)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32) (param $z i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (local.get $z)
+ )
+ )
+)
+;; bad index
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 5)
+ )
+ )
+)
+;; missing index
+(module
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 2)
+ )
+ )
+)
+;; bad type
+(module
+ ;; CHECK: (type $i32_=>_none (func (param i32)))
+
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+;; no table
+(module
+ ;; CHECK: (type $i32_=>_none (func (param i32)))
+
+ ;; CHECK: (func $foo (param $0 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32)
+ (unreachable)
+ )
+)
+;; change types
+(module
+ (type (func))
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (table $0 8 8 funcref)
+ (table $0 8 8 funcref)
+ ;; CHECK: (func $0
+ ;; CHECK-NEXT: (block $block
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $0
+ (block ;; the type of this block will change
+ (nop)
+ (call_indirect (type 0)
+ (i32.const 15)
+ )
+ )
+ )
+)
+(module ;; indirect tail call
+ ;; CHECK: (type $ii (func (param i32 i32)))
+ (type $ii (func (param i32 i32)))
+ ;; CHECK: (table $0 5 5 funcref)
+ (table $0 5 5 funcref)
+ (elem (i32.const 1) $foo)
+ ;; CHECK: (elem (i32.const 1) $foo)
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (return_call $foo
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (return_call_indirect (type $ii)
+ (local.get $x)
+ (local.get $y)
+ (i32.const 1)
+ )
+ )
+)
+;; call_ref
+(module
+ ;; CHECK: (type $i32_i32_=>_none (func (param i32 i32)))
+
+ ;; CHECK: (func $foo (param $0 i32) (param $1 i32)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $foo (param i32) (param i32)
+ (unreachable)
+ )
+ ;; CHECK: (func $bar (param $x i32) (param $y i32)
+ ;; CHECK-NEXT: (call $foo
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (param $x i32) (param $y i32)
+ (call_ref
+ (local.get $x)
+ (local.get $y)
+ (ref.func $foo)
+ )
+ )
+)
+