diff options
Diffstat (limited to 'test/lit/passes')
-rw-r--r-- | test/lit/passes/vacuum_all-features.wast | 1300 |
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) + ) + ) + ) + ) +) |