blob: 1a64521edcd59f6efcacb381371953080234ad39 [file] [log] [blame]
;; 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
;; 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
;; 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: (block $out2
;; CHECK-NEXT: (block $in2
;; CHECK-NEXT: (br $in2)
;; 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)
)
;; The second br will be removed. (The entire expression after us can also
;; be removed, which will be done by --remove-unused-brs --vacuum.)
(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
;; CHECK-NEXT: (f64.store align=1
;; CHECK-NEXT: (i32.const 879179022)
;; CHECK-NEXT: (block
;; CHECK-NEXT: (loop $label$9
;; CHECK-NEXT: (br $label$9)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 677803374)
;; CHECK-NEXT: )
;; 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
;; This loop never exits, so it is unreachable. We don't have much to
;; optimize here, but we can remove the br_if and leave an unreachable
;; block with the other contents for dce to clean up.
(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)
)
)
)
)
)