summaryrefslogtreecommitdiff
path: root/test/lit/passes
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit/passes')
-rw-r--r--test/lit/passes/vacuum_all-features.wast1300
1 files changed, 1300 insertions, 0 deletions
diff --git a/test/lit/passes/vacuum_all-features.wast b/test/lit/passes/vacuum_all-features.wast
new file mode 100644
index 000000000..36074af30
--- /dev/null
+++ b/test/lit/passes/vacuum_all-features.wast
@@ -0,0 +1,1300 @@
+;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
+;; NOTE: This test was ported using port_passes_tests_to_lit.py and could be cleaned up.
+
+;; RUN: foreach %s %t wasm-opt --vacuum --all-features -S -o - | filecheck %s
+
+(module
+ (memory 256 256)
+ ;; CHECK: (type $0 (func))
+ (type $0 (func))
+ ;; CHECK: (type $3 (func (result i32)))
+
+ ;; CHECK: (type $1 (func (param i32)))
+ (type $1 (func (param i32)))
+ ;; CHECK: (type $2 (func (result f32)))
+ (type $2 (func (result f32)))
+ (type $3 (func (result i32)))
+ ;; CHECK: (type $4 (func (param i32 f64 i32 i32)))
+ (type $4 (func (param i32 f64 i32 i32)))
+ (import $int "env" "int" (result i32))
+ ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32)))
+
+ ;; CHECK: (type $none_=>_f64 (func (result f64)))
+
+ ;; CHECK: (import "env" "int" (func $int (result i32)))
+
+ ;; CHECK: (global $Int i32 (i32.const 0))
+ (global $Int i32 (i32.const 0))
+ ;; CHECK: (memory $0 256 256)
+
+ ;; CHECK: (func $b (type $0)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $b (type $0)
+ (drop
+ (i32.const 50)
+ )
+ (nop)
+ (drop
+ (i32.const 51)
+ )
+ (nop)
+ (nop)
+ (drop
+ (i32.const 52)
+ )
+ (block $waka1
+ (drop
+ (i32.const 53)
+ )
+ (br $waka1)
+ (drop
+ (i32.const 54)
+ )
+ )
+ (block $waka2
+ (nop)
+ (br $waka2)
+ (drop
+ (i32.const 56)
+ )
+ )
+ (block $waka3
+ (br_table $waka3 $waka3 $waka3
+ (i32.const 57)
+ )
+ (drop
+ (i32.const 58)
+ )
+ )
+ (if
+ (i32.const 100)
+ (nop)
+ (drop
+ (i32.const 101)
+ )
+ )
+ (if
+ (i32.const 102)
+ (drop
+ (i32.const 103)
+ )
+ (nop)
+ )
+ (if
+ (i32.const 104)
+ (nop)
+ (nop)
+ )
+ )
+ ;; CHECK: (func $l (type $3) (result i32)
+ ;; CHECK-NEXT: (local $x i32)
+ ;; CHECK-NEXT: (local $y i32)
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (local.get $y)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ (func $l (result i32)
+ (local $x i32)
+ (local $y i32)
+ (drop
+ (local.get $x)
+ )
+ (local.set $x
+ (local.get $x)
+ )
+ (block $in-a-block
+ (drop
+ (local.get $x)
+ )
+ )
+ (block $two-in-a-block
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (local.get $y)
+ )
+ )
+ (local.set $x
+ (block $result-used (result i32)
+ (local.get $x)
+ )
+ )
+ (local.set $x
+ (block $two-and-result-used (result i32)
+ (drop
+ (local.get $x)
+ )
+ (local.get $y)
+ )
+ )
+ (local.get $x)
+ )
+ ;; CHECK: (func $loopy (type $1) (param $0 i32)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $loopy (type $1) (param $0 i32)
+ (loop $loop-in1
+ (nop)
+ )
+ (loop $loop-in3
+ (nop)
+ (nop)
+ )
+ (drop
+ (loop $loop-in5 (result i32)
+ (drop
+ (local.get $0)
+ )
+ (i32.const 20)
+ )
+ )
+ )
+ ;; CHECK: (func $unary (type $2) (result f32)
+ ;; CHECK-NEXT: (f32.abs
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unary (type $2) (result f32)
+ (drop
+ (f32.abs
+ (f32.const 1)
+ )
+ )
+ (f32.abs
+ (unreachable)
+ )
+ (f32.abs
+ (f32.const 2)
+ )
+ )
+ ;; CHECK: (func $binary (type $2) (result f32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (f32.add
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (f32.const 3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $binary (type $2) (result f32)
+ (drop
+ (f32.add
+ (f32.const 1)
+ (f32.const 2)
+ )
+ )
+ (drop
+ (f32.add
+ (unreachable)
+ (f32.const 3)
+ )
+ )
+ (drop
+ (f32.add
+ (f32.const 4)
+ (unreachable)
+ )
+ )
+ (f32.add
+ (unreachable)
+ (unreachable)
+ )
+ (f32.add
+ (f32.const 5)
+ (f32.const 6)
+ )
+ )
+ ;; CHECK: (func $select (type $3) (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (select
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (i32.const 4)
+ ;; CHECK-NEXT: (i32.const 5)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $select (type $3) (result i32)
+ (drop
+ (select
+ (i32.const 1)
+ (i32.const 2)
+ (i32.const 3)
+ )
+ )
+ (drop
+ (select
+ (unreachable)
+ (i32.const 4)
+ (i32.const 5)
+ )
+ )
+ (drop
+ (select
+ (i32.const 6)
+ (unreachable)
+ (i32.const 7)
+ )
+ )
+ (drop
+ (select
+ (i32.const 8)
+ (i32.const 9)
+ (unreachable)
+ )
+ )
+ (select
+ (unreachable)
+ (unreachable)
+ (i32.const 10)
+ )
+ (drop
+ (select
+ (unreachable)
+ (i32.const 11)
+ (unreachable)
+ )
+ )
+ (drop
+ (select
+ (i32.const 12)
+ (unreachable)
+ (unreachable)
+ )
+ )
+ (select
+ (unreachable)
+ (unreachable)
+ (unreachable)
+ )
+ (select
+ (i32.const 13)
+ (i32.const 14)
+ (i32.const 15)
+ )
+ )
+ ;; CHECK: (func $block-to-one (type $0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $block-to-one (type $0)
+ (block $block0
+ (nop)
+ (nop)
+ )
+ (block $block1
+ (nop)
+ (unreachable)
+ )
+ (block $block2
+ (nop)
+ (unreachable)
+ (nop)
+ )
+ (block $block3
+ (unreachable)
+ (nop)
+ )
+ (block $block4
+ (unreachable)
+ )
+ )
+ ;; CHECK: (func $recurse (type $0)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $recurse (type $0)
+ (nop)
+ (drop
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.const 1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $func-block (type $0)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $func-block (type $0)
+ (drop
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.abs
+ (f32.const 1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $Gu (type $4) (param $b i32) (param $e f64) (param $l i32) (param $d i32)
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (if (result i32)
+ ;; CHECK-NEXT: (local.get $d)
+ ;; CHECK-NEXT: (f64.ne
+ ;; CHECK-NEXT: (f64.promote_f32
+ ;; CHECK-NEXT: (f32.load
+ ;; CHECK-NEXT: (local.tee $l
+ ;; CHECK-NEXT: (i32.add
+ ;; CHECK-NEXT: (local.get $b)
+ ;; CHECK-NEXT: (i32.const 60)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $e)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $Gu (type $4) (param $b i32) (param $e f64) (param $l i32) (param $d i32)
+ (if
+ (if (result i32)
+ (local.get $d)
+ (block $block1 (result i32)
+ (nop)
+ (f64.ne
+ (f64.promote_f32
+ (f32.load
+ (local.tee $l
+ (i32.add
+ (local.get $b)
+ (i32.const 60)
+ )
+ )
+ )
+ )
+ (local.get $e)
+ )
+ )
+ (i32.const 0)
+ )
+ (unreachable)
+ )
+ )
+ ;; CHECK: (func $if-drop (type $3) (result i32)
+ ;; CHECK-NEXT: (block $out
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (call $if-drop)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $int)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (br $out)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (call $if-drop)
+ ;; CHECK-NEXT: (br $out)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $int)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ (func $if-drop (result i32)
+ (block $out
+ (drop
+ (if (result i32)
+ (call $if-drop)
+ (call $int)
+ (br $out)
+ )
+ )
+ (drop
+ (if (result i32)
+ (call $if-drop)
+ (br $out)
+ (call $int)
+ )
+ )
+ )
+ (i32.const 1)
+ )
+ ;; CHECK: (func $drop-silly (type $0)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $int)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $int)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $int)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $int)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $int)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $drop-silly
+ (drop
+ (i32.eqz
+ (i32.eqz
+ (i32.const 1)
+ )
+ )
+ )
+ (drop
+ (i32.eqz
+ (i32.eqz
+ (call $int)
+ )
+ )
+ )
+ (drop
+ (i32.add
+ (i32.const 2)
+ (i32.const 3)
+ )
+ )
+ (drop
+ (i32.add
+ (i32.const 4)
+ (call $int)
+ )
+ )
+ (drop
+ (i32.add
+ (call $int)
+ (i32.const 5)
+ )
+ )
+ (drop
+ (i32.add
+ (call $int)
+ (call $int)
+ )
+ )
+ )
+ ;; CHECK: (func $drop-get-global (type $0)
+ ;; CHECK-NEXT: (call $drop-get-global)
+ ;; CHECK-NEXT: )
+ (func $drop-get-global
+ (drop
+ (block (result i32)
+ (call $drop-get-global)
+ (global.get $Int) ;; this is not needed due to the block being drop'd, but make sure the call is not then dropped either
+ )
+ )
+ )
+ ;; CHECK: (func $relooperJumpThreading1 (type $0)
+ ;; CHECK-NEXT: (local $$vararg_ptr5 i32)
+ ;; CHECK-NEXT: (local $$11 i32)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $relooperJumpThreading1
+ (local $$vararg_ptr5 i32)
+ (local $$11 i32)
+ (loop $while-in$1
+ (drop
+ (block $jumpthreading$outer$8 (result i32)
+ (block $jumpthreading$inner$8
+ (br $jumpthreading$outer$8 ;; the rest is dead in the outer block, but be careful to leave the return value!
+ (i32.const 0)
+ )
+ )
+ (i32.store
+ (local.get $$vararg_ptr5)
+ (local.get $$11)
+ )
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $relooperJumpThreading2 (type $0)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $relooperJumpThreading2
+ (loop $while-in$1
+ (drop
+ (block $jumpthreading$outer$8 (result i32)
+ (block $jumpthreading$inner$8
+ (br $jumpthreading$outer$8
+ (i32.const 0)
+ )
+ )
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $relooperJumpThreading3 (type $0)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $relooperJumpThreading3
+ (loop $while-in$1
+ (drop
+ (block $jumpthreading$outer$8 (result i32)
+ (br $jumpthreading$outer$8 ;; code after this is dead, can kill it, but preserve the return value at the end!
+ (i32.const 0)
+ )
+ (drop (i32.const 3))
+ (drop (i32.const 2))
+ (drop (i32.const 1))
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $if2drops (type $3) (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (if (result i32)
+ ;; CHECK-NEXT: (call $if2drops)
+ ;; CHECK-NEXT: (call $if2drops)
+ ;; CHECK-NEXT: (call $if2drops)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ (func $if2drops (result i32)
+ (if
+ (call $if2drops)
+ (drop
+ (call $if2drops)
+ )
+ (drop
+ (call $if2drops)
+ )
+ )
+ (i32.const 2)
+ )
+ ;; CHECK: (func $if2drops-different (type $3) (result i32)
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (call $if2drops)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $if2drops)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (call $unary)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ (func $if2drops-different (result i32)
+ (if
+ (call $if2drops)
+ (drop
+ (call $if2drops) ;; i32
+ )
+ (drop
+ (call $unary) ;; f32!
+ )
+ )
+ (i32.const 2)
+ )
+ ;; CHECK: (func $if-const (type $1) (param $x i32)
+ ;; CHECK-NEXT: (call $if-const
+ ;; CHECK-NEXT: (i32.const 3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $if-const
+ ;; CHECK-NEXT: (i32.const 5)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $if-const
+ ;; CHECK-NEXT: (i32.const 7)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $if-const (param $x i32)
+ (if (i32.const 0) (call $if-const (i32.const 1)))
+ (if (i32.const 2) (call $if-const (i32.const 3)))
+ (if (i32.const 0) (call $if-const (i32.const 4)) (call $if-const (i32.const 5)))
+ (if (i32.const 6) (call $if-const (i32.const 7)) (call $if-const (i32.const 8)))
+ )
+ ;; CHECK: (func $drop-if-both-unreachable (type $1) (param $0 i32)
+ ;; CHECK-NEXT: (block $out
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (if (result i32)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (br $out)
+ ;; CHECK-NEXT: (br $out)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (if (result i32)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $drop-if-both-unreachable (param $0 i32)
+ (block $out
+ (drop
+ (if (result i32)
+ (local.get $0)
+ (br $out)
+ (br $out)
+ )
+ )
+ )
+ (drop
+ (if (result i32)
+ (local.get $0)
+ (unreachable)
+ (unreachable)
+ )
+ )
+ )
+ ;; CHECK: (func $if-1-block (type $i32_=>_i32) (param $x i32) (result i32)
+ ;; CHECK-NEXT: (block $out
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (local.set $x
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (br $out)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.get $x)
+ ;; CHECK-NEXT: )
+ (func $if-1-block (param $x i32) (result i32)
+ (block $out
+ (if
+ (local.get $x)
+ (block
+ (if
+ (i32.const 1)
+ (block
+ (local.set $x
+ (local.get $x)
+ )
+ (br $out)
+ )
+ )
+ )
+ )
+ )
+ (local.get $x)
+ )
+ ;; CHECK: (func $block-resize-br-gone (type $0)
+ ;; CHECK-NEXT: (block $out
+ ;; CHECK-NEXT: (block $in
+ ;; CHECK-NEXT: (call $block-resize-br-gone)
+ ;; CHECK-NEXT: (br $in)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (return)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $block-resize-br-gone
+ (block $out
+ (block $in
+ (call $block-resize-br-gone)
+ (br $in)
+ (br $out)
+ )
+ (return)
+ )
+ (block $out2
+ (block $in2
+ (br $in2)
+ (br $out2)
+ )
+ (return)
+ )
+ )
+ ;; CHECK: (func $block-unreachable-but-last-element-concrete (type $0)
+ ;; CHECK-NEXT: (local $2 i32)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $block-unreachable-but-last-element-concrete
+ (local $2 i32)
+ (block $label$0
+ (drop
+ (block (result i32)
+ (br $label$0)
+ (local.get $2)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $a (type $0)
+ ;; CHECK-NEXT: (i32.store
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (f64.div
+ ;; CHECK-NEXT: (f64.const -nan:0xfffffffffa361)
+ ;; CHECK-NEXT: (loop $label$1
+ ;; CHECK-NEXT: (br $label$1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $a
+ (block
+ (i32.store (i32.const 1) (i32.const 2))
+ (f64.div
+ (f64.const -nan:0xfffffffffa361)
+ (loop $label$1 ;; unreachable, so the div is too. keep
+ (br $label$1)
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $leave-block-even-if-br-not-taken (type $none_=>_f64) (result f64)
+ ;; CHECK-NEXT: (block $label$0 (result f64)
+ ;; CHECK-NEXT: (f64.store align=1
+ ;; CHECK-NEXT: (i32.const 879179022)
+ ;; CHECK-NEXT: (br_if $label$0
+ ;; CHECK-NEXT: (loop $label$9
+ ;; CHECK-NEXT: (br $label$9)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 677803374)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $leave-block-even-if-br-not-taken (result f64)
+ (block $label$0 (result f64)
+ (f64.store align=1
+ (i32.const 879179022)
+ (br_if $label$0
+ (loop $label$9
+ (br $label$9)
+ )
+ (i32.const 677803374)
+ )
+ )
+ (f64.const 2097914503796645752267195e31)
+ )
+ )
+ ;; CHECK: (func $executed-if-in-block (type $0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $executed-if-in-block
+ (block $label$0
+ (if
+ (i32.const 170996275)
+ (unreachable)
+ (br $label$0)
+ )
+ )
+ (unreachable)
+ )
+ ;; CHECK: (func $executed-if-in-block2 (type $0)
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $executed-if-in-block2
+ (block $label$0
+ (if
+ (i32.const 170996275)
+ (nop)
+ (br $label$0)
+ )
+ )
+ (unreachable)
+ )
+ ;; CHECK: (func $executed-if-in-block3 (type $0)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (br $label$0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $executed-if-in-block3
+ (block $label$0
+ (if
+ (i32.const 170996275)
+ (br $label$0)
+ (nop)
+ )
+ )
+ (unreachable)
+ )
+ ;; CHECK: (func $load-may-have-side-effects (type $3) (result i32)
+ ;; CHECK-NEXT: (i64.ge_s
+ ;; CHECK-NEXT: (block (result i64)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i64.load32_s
+ ;; CHECK-NEXT: (i32.const 678585719)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i64.const 2912825531628789796)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i64.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $load-may-have-side-effects (result i32)
+ (i64.ge_s
+ (block (result i64)
+ (drop
+ (i64.eq
+ (i64.load32_s
+ (i32.const 678585719)
+ )
+ (i64.const 8097879367757079605)
+ )
+ )
+ (i64.const 2912825531628789796)
+ )
+ (i64.const 0)
+ )
+ )
+ ;; CHECK: (func $unary-binary-may-trap (type $0)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (i64.trunc_f32_u
+ ;; CHECK-NEXT: (f32.const 70847791997969805621592064)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unary-binary-may-trap
+ (drop
+ (i64.div_s
+ (i64.const -1)
+ (i64.const 729618461987467893)
+ )
+ )
+ (drop
+ (i64.trunc_f32_u
+ (f32.const 70847791997969805621592064)
+ )
+ )
+ )
+ ;; CHECK: (func $unreachable-if-with-nop-arm-that-leaves-a-concrete-value-if-nop-is-removed (type $0)
+ ;; CHECK-NEXT: (block $label$0
+ ;; CHECK-NEXT: (loop $label$1
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (br_if $label$0
+ ;; CHECK-NEXT: (loop $label$9
+ ;; CHECK-NEXT: (br $label$9)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $unreachable-if-with-nop-arm-that-leaves-a-concrete-value-if-nop-is-removed
+ (block $label$0
+ (loop $label$1
+ (drop
+ (if (result i32)
+ (br_if $label$0
+ (loop $label$9
+ (br $label$9)
+ )
+ )
+ (unreachable)
+ (i32.const 1920103026)
+ )
+ )
+ )
+ )
+ )
+ ;; CHECK: (func $if-arm-vanishes (type $3) (result i32)
+ ;; CHECK-NEXT: (block $label$0 (result i32)
+ ;; CHECK-NEXT: (br $label$0
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $if-arm-vanishes (result i32)
+ (block $label$0 (result i32)
+ (block $label$1
+ (if
+ (br $label$0
+ (i32.const 1)
+ )
+ (br $label$1)
+ )
+ )
+ (i32.const 1579493952)
+ )
+ )
+ ;; CHECK: (func $if-arm-vanishes-2 (type $3) (result i32)
+ ;; CHECK-NEXT: (block $label$0 (result i32)
+ ;; CHECK-NEXT: (br $label$0
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $if-arm-vanishes-2 (result i32)
+ (block $label$0 (result i32)
+ (block $label$1
+ (if
+ (br $label$0
+ (i32.const 1)
+ )
+ (br $label$1)
+ )
+ )
+ (i32.const 1579493952)
+ )
+ )
+ ;; CHECK: (func $nop-if-type-changes (type $0)
+ ;; CHECK-NEXT: (local $0 i32)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $nop-if-type-changes (type $0)
+ (local $0 i32)
+ (block $label$0
+ (if
+ (i32.eqz
+ (local.get $0)
+ )
+ (block $label$1
+ (block
+ (if ;; we nop this if, which has a type change for block $label$1, no more brs to it
+ (i32.const 0)
+ (br_if $label$1
+ (i32.const 1717966400)
+ )
+ )
+ (drop
+ (br $label$0)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+(module ;; a child with a different type, cannot simply replace the parent with it
+ ;; CHECK: (type $0 (func (param i64)))
+ (type $0 (func (param i64)))
+ ;; CHECK: (type $1 (func (param f32 i32) (result i32)))
+ (type $1 (func (param f32 i32) (result i32)))
+ ;; CHECK: (func $0 (type $0) (param $0 i64)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $0 (; 0 ;) (type $0) (param $0 i64)
+ (nop)
+ )
+ ;; CHECK: (func $1 (type $1) (param $0 f32) (param $1 i32) (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block $label$2 (result i64)
+ ;; CHECK-NEXT: (call $0
+ ;; CHECK-NEXT: (br_if $label$2
+ ;; CHECK-NEXT: (i64.const -137438953472)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ (func $1 (; 1 ;) (type $1) (param $0 f32) (param $1 i32) (result i32)
+ (drop
+ (block $label$1 (result i32)
+ (i32.wrap_i64
+ (block $label$2 (result i64)
+ (call $0
+ (br_if $label$2
+ (i64.const -137438953472)
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ )
+ )
+ )
+ (unreachable)
+ )
+)
+(module ;; vacuum away a drop on an if where both arms can be vacuumed
+ (memory 1 1)
+ ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32)))
+
+ ;; CHECK: (type $i32_i32_i32_=>_none (func (param i32 i32 i32)))
+
+ ;; CHECK: (global $global$1 (mut i32) (i32.const 0))
+ (global $global$1 (mut i32) (i32.const 0))
+ ;; CHECK: (memory $0 1 1)
+
+ ;; CHECK: (export "compress" (func $3))
+
+ ;; CHECK: (func $_deflate (type $i32_=>_i32) (param $0 i32) (result i32)
+ ;; CHECK-NEXT: (call $_deflate
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $_deflate (param i32) (result i32)
+ (call $_deflate (local.get $0))
+ )
+ ;; CHECK: (func $_deflateInit2_ (type $i32_=>_i32) (param $0 i32) (result i32)
+ ;; CHECK-NEXT: (call $_deflateInit2_
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $_deflateInit2_ (param i32) (result i32)
+ (call $_deflateInit2_ (local.get $0))
+ )
+ ;; CHECK: (func $_deflateEnd (type $i32_=>_i32) (param $0 i32) (result i32)
+ ;; CHECK-NEXT: (call $_deflateEnd
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $_deflateEnd (param i32) (result i32)
+ (call $_deflateEnd (local.get $0))
+ )
+ (func "compress" (param $0 i32) (param $1 i32) (param $2 i32)
+ (local $3 i32)
+ (local.set $3
+ (global.get $global$1)
+ )
+ (global.set $global$1
+ (i32.sub
+ (global.get $global$1)
+ (i32.const -64)
+ )
+ )
+ (i32.store
+ (local.get $3)
+ (local.get $2)
+ )
+ (i32.store offset=4
+ (local.get $3)
+ (i32.const 100000)
+ )
+ (i32.store offset=12
+ (local.get $3)
+ (local.get $0)
+ )
+ (i32.store offset=16
+ (local.get $3)
+ (i32.load
+ (local.get $1)
+ )
+ )
+ (i32.store offset=32
+ (local.get $3)
+ (i32.const 0)
+ )
+ (i32.store offset=36
+ (local.get $3)
+ (i32.const 0)
+ )
+ (i32.store offset=40
+ (local.get $3)
+ (i32.const 0)
+ )
+ (if
+ (call $_deflateInit2_
+ (local.get $3)
+ )
+ (block
+ (global.set $global$1
+ (local.get $3)
+ )
+ (return)
+ )
+ )
+ (drop
+ (if (result i32)
+ (i32.eq
+ (local.tee $0
+ (call $_deflate
+ (local.get $3)
+ )
+ )
+ (i32.const 1)
+ )
+ (block (result i32)
+ (i32.store
+ (local.get $1)
+ (i32.load offset=20
+ (local.get $3)
+ )
+ )
+ (local.set $0
+ (call $_deflateEnd
+ (local.get $3)
+ )
+ )
+ (global.set $global$1
+ (local.get $3)
+ )
+ (local.get $0)
+ )
+ (block (result i32)
+ (drop
+ (call $_deflateEnd
+ (local.get $3)
+ )
+ )
+ (global.set $global$1
+ (local.get $3)
+ )
+ (select
+ (local.get $0)
+ (i32.const -5)
+ (local.get $0)
+ )
+ )
+ )
+ )
+ )
+)
+
+;; CHECK: (func $3 (type $i32_i32_i32_=>_none) (param $0 i32) (param $1 i32) (param $2 i32)
+;; CHECK-NEXT: (local $3 i32)
+;; CHECK-NEXT: (local.set $3
+;; CHECK-NEXT: (global.get $global$1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $global$1
+;; CHECK-NEXT: (i32.sub
+;; CHECK-NEXT: (global.get $global$1)
+;; CHECK-NEXT: (i32.const -64)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: (local.get $2)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=4
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: (i32.const 100000)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=12
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: (local.get $0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=16
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: (i32.load
+;; CHECK-NEXT: (local.get $1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=32
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=36
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.store offset=40
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (if
+;; CHECK-NEXT: (call $_deflateInit2_
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block
+;; CHECK-NEXT: (global.set $global$1
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (return)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (if (result i32)
+;; CHECK-NEXT: (i32.eq
+;; CHECK-NEXT: (local.tee $0
+;; CHECK-NEXT: (call $_deflate
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 1)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block (result i32)
+;; CHECK-NEXT: (i32.store
+;; CHECK-NEXT: (local.get $1)
+;; CHECK-NEXT: (i32.load offset=20
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (local.set $0
+;; CHECK-NEXT: (call $_deflateEnd
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $global$1
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (block (result i32)
+;; CHECK-NEXT: (drop
+;; CHECK-NEXT: (call $_deflateEnd
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (global.set $global$1
+;; CHECK-NEXT: (local.get $3)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: (i32.const 0)
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+;; CHECK-NEXT: )
+(module
+ (type $A (struct (field (mut i32))))
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (func $foo (type $none_=>_none)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $foo
+ (drop
+ (block (result structref)
+ ;; this dropped item can be vacuumed out in principle, but it is a non-
+ ;; nullable reference type and we don't have a type to put in its place, so
+ ;; don't try to replace it. (later operations will remove all the body of
+ ;; this function; this test verifies we don't crash along the way)
+ (struct.new_default $A)
+ )
+ )
+ )
+)
+(module
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (global $global$0 (mut i32) (i32.const 10))
+ (global $global$0 (mut i32) (i32.const 10))
+ ;; CHECK: (func $1 (type $none_=>_none)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $1
+ (drop
+ (block $block (result funcref i32)
+ ;; we can vaccum out all parts of this block: the br_if is not taken, there
+ ;; is a nop, and the tuple at the end goes to a dropped block anyhow. this
+ ;; test specifically verifies handling of tuples containing non-nullable
+ ;; types, for which we try to create a zero in an intermediate step along
+ ;; the way.
+ (drop
+ (br_if $block
+ (tuple.make
+ (ref.func $1)
+ (i32.const 0)
+ )
+ (i32.const 0)
+ )
+ )
+ (nop)
+ (tuple.make
+ (ref.func $1)
+ (i32.const 1)
+ )
+ )
+ )
+ )
+)