blob: 321fbab81466bc5b8a37fb7c04bc38feef95d4da [file] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
;; RUN: wasm-opt %s --remove-unused-brs -all -S -o - \
;; RUN: | filecheck %s
(module
;; CHECK: (import "a" "b" (func $i32 (type $3) (result i32)))
(import "a" "b" (func $i32 (result i32)))
;; CHECK: (import "a" "b" (func $none (type $2)))
(import "a" "b" (func $none))
;; CHECK: (tag $e (type $2))
(tag $e)
;; CHECK: (func $if-br (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (block $out
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (br_if $out
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-br (param $x i32) (param $y i32)
(block $out
;; This nop prevents the entire testcase from being trivial.
(nop)
;; The if-br will turn into a br_if. The branch hint should then go on the
;; br_if, and remain 01.
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(br $out)
)
)
)
)
;; CHECK: (func $if-br_0 (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (block $out
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (br_if $out
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-br_0 (param $x i32) (param $y i32)
(block $out
(nop)
;; As above, but a hint of 0.
(@metadata.code.branch_hint "\00")
(if
(local.get $x)
(then
(br $out)
)
)
)
)
;; CHECK: (func $if-br_if (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (block $out
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (br_if $out
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-br_if (param $x i32) (param $y i32)
(block $out
(nop)
;; As above, but the br has a condition. We can merge conditions (using a
;; select), and then move the hint to the br_if, as the br_if has the
;; same hint as the if.
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\01")
(br_if $out
(local.get $y)
)
)
)
)
)
;; CHECK: (func $if-br_if-no (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (block $out
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (br_if $out
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-br_if-no (param $x i32) (param $y i32)
(block $out
(nop)
;; As above, but the br lacks a hint, so we emit no hint.
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(br_if $out
(local.get $y)
)
)
)
)
)
;; CHECK: (func $if-br_if-no-2 (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (block $out
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (br_if $out
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-br_if-no-2 (param $x i32) (param $y i32)
(block $out
(nop)
;; As above, but now the if lacks a hint, so we emit no hint.
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\01")
(br_if $out
(local.get $y)
)
)
)
)
)
;; CHECK: (func $if-if-1* (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-if-1* (param $x i32) (param $y i32)
;; Both ifs have a hint of 1, so after we merge the ifs the combined
;; condition remains likely.
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\01")
(if
(local.get $y)
(then
(call $none)
)
)
)
)
;; The outer if still has a hint of 1, but the inner is 0. We emit no hint.
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\00")
(if
(local.get $y)
(then
(call $none)
)
)
)
)
;; The outer if still has a hint of 1, but the inner has none. We emit no
;; hint.
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(if
(local.get $y)
(then
(call $none)
)
)
)
)
)
;; CHECK: (func $if-if-0* (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-if-0* (param $x i32) (param $y i32)
;; As above, but now the outer if has hints of 0.
;; The hints do not match, so we emit no hint.
(@metadata.code.branch_hint "\00")
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\01")
(if
(local.get $y)
(then
(call $none)
)
)
)
)
;; The hints match, so the combined condition is unlikely.
(@metadata.code.branch_hint "\00")
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\00")
(if
(local.get $y)
(then
(call $none)
)
)
)
)
;; Inner lacks a hint, so we emit nothing.
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(if
(local.get $y)
(then
(call $none)
)
)
)
)
)
;; CHECK: (func $if-if-?* (type $1) (param $x i32) (param $y i32)
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (if
;; CHECK-NEXT: (select
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: (local.get $y)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $if-if-?* (param $x i32) (param $y i32)
;; As above, but now the outer if has no hint. We emit no hints here.
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\01")
(if
(local.get $y)
(then
(call $none)
)
)
)
)
(if
(local.get $x)
(then
(@metadata.code.branch_hint "\00")
(if
(local.get $y)
(then
(call $none)
)
)
)
)
(if
(local.get $x)
(then
(if
(local.get $y)
(then
(call $none)
)
)
)
)
)
;; CHECK: (func $loop-br_if-flip (type $0) (param $x i32)
;; CHECK-NEXT: (loop $loop
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (block
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (br_if $loop
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $loop-br_if-flip (param $x i32)
(block $block
(loop $loop
;; This br_if's condition will flip when it is turned from a break out
;; of the loop to a continue inside it. The hint should flip too.
(@metadata.code.branch_hint "\00")
(br_if $block
(local.get $x)
)
(br $loop)
)
)
)
;; CHECK: (func $loop-br_if-flip-reverse (type $0) (param $x i32)
;; CHECK-NEXT: (loop $loop
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (block
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (br_if $loop
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $loop-br_if-flip-reverse (param $x i32)
;; As above, with a hint of 1, that should flip to 0.
(block $block
(loop $loop
(@metadata.code.branch_hint "\01")
(br_if $block
(local.get $x)
)
(br $loop)
)
)
)
;; CHECK: (func $loop-br_if-if (type $0) (param $x i32)
;; CHECK-NEXT: (loop $loop
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (if
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (then
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (else
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (i32.const 42)
;; CHECK-NEXT: )
;; CHECK-NEXT: (br $loop)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $loop-br_if-if (param $x i32)
(loop $loop
(block $block
;; This br_if will turn into an if with the same condition. The hint can
;; be copied over.
(@metadata.code.branch_hint "\00")
(br_if $block
(local.get $x)
)
;; Extra code so simpler optimizations do not kick in.
(drop (i32.const 42))
(br $loop)
)
)
)
;; CHECK: (func $throw-if-br_if-0 (type $0) (param $x i32)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch_all $catch)
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (br_if $catch
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $throw-if-br_if-0 (param $x i32)
(block $catch
(try_table (catch_all $catch)
;; This if can turn into a br_if. The branch hint should be copied.
(@metadata.code.branch_hint "\00")
(if
(local.get $x)
(then
(throw $e)
)
)
)
)
)
;; CHECK: (func $throw-if-br_if-1 (type $0) (param $x i32)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch_all $catch)
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (br_if $catch
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $throw-if-br_if-1 (param $x i32)
;; As above, but the hint is 1.
(block $catch
(try_table (catch_all $catch)
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(throw $e)
)
)
)
)
)
;; CHECK: (func $throw-if-br_if-no (type $0) (param $x i32)
;; CHECK-NEXT: (block $catch
;; CHECK-NEXT: (try_table (catch_all $catch)
;; CHECK-NEXT: (br_if $catch
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $throw-if-br_if-no (param $x i32)
;; As above, but there is no branch hint, so we should emit none.
(block $catch
(try_table (catch_all $catch)
(if
(local.get $x)
(then
(throw $e)
)
)
)
)
)
;; CHECK: (func $loop-if-br (type $0) (param $x i32)
;; CHECK-NEXT: (loop $loop
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (br_if $loop
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $loop-if-br (param $x i32)
;; This if with a br arm can turn into a br_if. The hint should be copied.
(loop $loop
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(br $loop)
)
(else
;; This call, and the one below, are needed for the pattern that is
;; recognized here.
(call $none)
)
)
(call $none)
)
)
;; CHECK: (func $loop-if-br-reverse (type $0) (param $x i32)
;; CHECK-NEXT: (loop $loop
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (br_if $loop
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $loop-if-br-reverse (param $x i32)
;; As above, with arms flipped. Now the condition flips.
(loop $loop
(@metadata.code.branch_hint "\01")
(if
(local.get $x)
(then
(call $none)
)
(else
(br $loop)
)
)
(call $none)
)
)
;; CHECK: (func $restructure-if (type $0) (param $x i32)
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (if
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (block $block
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (call $none)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $restructure-if (param $x i32)
(block $block
;; We will emit an if with flipped condition, which should get a flipped
;; hint.
(@metadata.code.branch_hint "\01")
(br_if $block
(local.get $x)
)
(call $none)
)
)
;; CHECK: (func $restructure-if-value (type $4) (param $x i32) (result i32)
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (if (result i32)
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: (then
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: (else
;; CHECK-NEXT: (block $value (result i32)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $restructure-if-value (param $x i32) (result i32)
;; We will emit an if with the same condition, which should get the same
;; hint.
(block $value (result i32)
(drop
(@metadata.code.branch_hint "\01")
(br_if $value
(i32.const 0)
(local.get $x)
)
)
(unreachable)
)
)
;; CHECK: (func $set-if-br-arm (type $0) (param $x i32)
;; CHECK-NEXT: (local $temp i32)
;; CHECK-NEXT: (block $out
;; CHECK-NEXT: (block
;; CHECK-NEXT: (@metadata.code.branch_hint "\00")
;; CHECK-NEXT: (br_if $out
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $temp
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $set-if-br-arm (param $x i32)
(local $temp i32)
;; The if will turn into a br_if, with the same hint.
(block $out
(local.set $temp
(@metadata.code.branch_hint "\00")
(if (result i32)
(local.get $x)
(then
(br $out)
)
(else
(i32.const 0)
)
)
)
)
)
;; CHECK: (func $set-if-br-arm-flip (type $0) (param $x i32)
;; CHECK-NEXT: (local $temp i32)
;; CHECK-NEXT: (block $out
;; CHECK-NEXT: (block
;; CHECK-NEXT: (@metadata.code.branch_hint "\01")
;; CHECK-NEXT: (br_if $out
;; CHECK-NEXT: (i32.eqz
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (local.set $temp
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $set-if-br-arm-flip (param $x i32)
(local $temp i32)
;; As above, but with arms reversed.
;; The if will turn into a flipped br_if, with a flipped hint.
(block $out
(local.set $temp
(@metadata.code.branch_hint "\00")
(if (result i32)
(local.get $x)
(then
(i32.const 0)
)
(else
(br $out)
)
)
)
)
)
)