| ;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited. |
| ;; Test that optimize-instructions turns resumptions of continuations that never |
| ;; suspend into direct calls. |
| |
| ;; RUN: wasm-opt %s --all-features --generate-global-effects --optimize-instructions -S -o - | filecheck %s --check-prefix NO-TNH |
| ;; RUN: wasm-opt %s --all-features --generate-global-effects --traps-never-happen --optimize-instructions -S -o - | filecheck %s --check-prefix TNH |
| ;; RUN: wasm-opt %s --all-features --generate-global-effects --optimize-instructions --vacuum -S -o - | filecheck %s --check-prefix VACUUM |
| |
| (module |
| ;; NO-TNH: (type $sig-none (func)) |
| |
| ;; NO-TNH: (type $cont-none (cont $sig-none)) |
| |
| ;; NO-TNH: (type $sig-binary (func (param i32 i32) (result i32))) |
| |
| ;; NO-TNH: (type $cont-binary (cont $sig-binary)) |
| |
| ;; NO-TNH: (type $sig-unary (func (param i32) (result i32))) |
| |
| ;; NO-TNH: (type $sig-any (func (param (ref any)) (result (ref any)))) |
| |
| ;; NO-TNH: (import "env" "imported" (func $imported (type $sig-none))) |
| ;; TNH: (type $sig-none (func)) |
| |
| ;; TNH: (type $cont-none (cont $sig-none)) |
| |
| ;; TNH: (type $sig-binary (func (param i32 i32) (result i32))) |
| |
| ;; TNH: (type $cont-binary (cont $sig-binary)) |
| |
| ;; TNH: (type $sig-unary (func (param i32) (result i32))) |
| |
| ;; TNH: (type $sig-any (func (param (ref any)) (result (ref any)))) |
| |
| ;; TNH: (import "env" "imported" (func $imported (type $sig-none))) |
| ;; VACUUM: (type $sig-none (func)) |
| |
| ;; VACUUM: (type $cont-none (cont $sig-none)) |
| |
| ;; VACUUM: (type $sig-binary (func (param i32 i32) (result i32))) |
| |
| ;; VACUUM: (type $cont-binary (cont $sig-binary)) |
| |
| ;; VACUUM: (type $sig-unary (func (param i32) (result i32))) |
| |
| ;; VACUUM: (type $sig-any (func (param (ref any)) (result (ref any)))) |
| |
| ;; VACUUM: (import "env" "imported" (func $imported (type $sig-none))) |
| (import "env" "imported" (func $imported (type $sig-none))) |
| |
| ;; NO-TNH: (global $counter (mut i32) (i32.const 0)) |
| |
| ;; NO-TNH: (tag $tag (type $sig-none)) |
| ;; TNH: (global $counter (mut i32) (i32.const 0)) |
| |
| ;; TNH: (tag $tag (type $sig-none)) |
| ;; VACUUM: (global $counter (mut i32) (i32.const 0)) |
| |
| ;; VACUUM: (tag $tag (type $sig-none)) |
| (tag $tag) |
| ;; NO-TNH: (tag $tag-i32 (type $7) (param i32)) |
| ;; TNH: (tag $tag-i32 (type $7) (param i32)) |
| ;; VACUUM: (tag $tag-i32 (type $7) (param i32)) |
| (tag $tag-i32 (param i32)) |
| |
| (type $sig-none (func)) |
| (type $sig-binary (func (param i32 i32) (result i32))) |
| (type $sig-unary (func (param i32) (result i32))) |
| (type $sig-any (func (param (ref any)) (result (ref any)))) |
| |
| (type $cont-none (cont $sig-none)) |
| (type $cont-binary (cont $sig-binary)) |
| (type $cont-unary (cont $sig-unary)) |
| (type $cont-any (cont $sig-any)) |
| |
| (global $counter (mut i32) (i32.const 0)) |
| |
| ;; NO-TNH: (func $pure (type $sig-none) |
| ;; NO-TNH-NEXT: (nop) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $pure (type $sig-none) |
| ;; TNH-NEXT: (nop) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $pure (type $sig-none) |
| ;; VACUUM-NEXT: (nop) |
| ;; VACUUM-NEXT: ) |
| (func $pure (type $sig-none) |
| (nop) |
| ) |
| |
| ;; NO-TNH: (func $pure-binary (type $sig-binary) (param $x i32) (param $y i32) (result i32) |
| ;; NO-TNH-NEXT: (i32.add |
| ;; NO-TNH-NEXT: (local.get $x) |
| ;; NO-TNH-NEXT: (local.get $y) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $pure-binary (type $sig-binary) (param $x i32) (param $y i32) (result i32) |
| ;; TNH-NEXT: (i32.add |
| ;; TNH-NEXT: (local.get $x) |
| ;; TNH-NEXT: (local.get $y) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $pure-binary (type $sig-binary) (param $x i32) (param $y i32) (result i32) |
| ;; VACUUM-NEXT: (i32.add |
| ;; VACUUM-NEXT: (local.get $x) |
| ;; VACUUM-NEXT: (local.get $y) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $pure-binary (type $sig-binary) (param $x i32) (param $y i32) (result i32) |
| (i32.add (local.get $x) (local.get $y)) |
| ) |
| |
| ;; NO-TNH: (func $pure-any (type $sig-any) (param $x (ref any)) (result (ref any)) |
| ;; NO-TNH-NEXT: (local.get $x) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $pure-any (type $sig-any) (param $x (ref any)) (result (ref any)) |
| ;; TNH-NEXT: (local.get $x) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $pure-any (type $sig-any) (param $x (ref any)) (result (ref any)) |
| ;; VACUUM-NEXT: (local.get $x) |
| ;; VACUUM-NEXT: ) |
| (func $pure-any (type $sig-any) (param $x (ref any)) (result (ref any)) |
| (local.get $x) |
| ) |
| |
| ;; NO-TNH: (func $suspending (type $sig-none) |
| ;; NO-TNH-NEXT: (suspend $tag) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $suspending (type $sig-none) |
| ;; TNH-NEXT: (suspend $tag) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $suspending (type $sig-none) |
| ;; VACUUM-NEXT: (suspend $tag) |
| ;; VACUUM-NEXT: ) |
| (func $suspending (type $sig-none) |
| (suspend $tag) |
| ) |
| |
| ;; NO-TNH: (func $caller-of-suspending (type $sig-none) |
| ;; NO-TNH-NEXT: (call $suspending) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $caller-of-suspending (type $sig-none) |
| ;; TNH-NEXT: (call $suspending) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $caller-of-suspending (type $sig-none) |
| ;; VACUUM-NEXT: (call $suspending) |
| ;; VACUUM-NEXT: ) |
| (func $caller-of-suspending (type $sig-none) |
| (call $suspending) |
| ) |
| |
| ;; NO-TNH: (func $same-sig-pure (type $sig-unary) (param $x i32) (result i32) |
| ;; NO-TNH-NEXT: (local.get $x) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $same-sig-pure (type $sig-unary) (param $x i32) (result i32) |
| ;; TNH-NEXT: (local.get $x) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $same-sig-pure (type $sig-unary) (param $x i32) (result i32) |
| ;; VACUUM-NEXT: (local.get $x) |
| ;; VACUUM-NEXT: ) |
| (func $same-sig-pure (type $sig-unary) (param $x i32) (result i32) |
| (local.get $x) |
| ) |
| |
| ;; NO-TNH: (func $same-sig-suspending (type $sig-unary) (param $x i32) (result i32) |
| ;; NO-TNH-NEXT: (suspend $tag-i32 |
| ;; NO-TNH-NEXT: (local.get $x) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (local.get $x) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $same-sig-suspending (type $sig-unary) (param $x i32) (result i32) |
| ;; TNH-NEXT: (suspend $tag-i32 |
| ;; TNH-NEXT: (local.get $x) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (local.get $x) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $same-sig-suspending (type $sig-unary) (param $x i32) (result i32) |
| ;; VACUUM-NEXT: (suspend $tag-i32 |
| ;; VACUUM-NEXT: (local.get $x) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (local.get $x) |
| ;; VACUUM-NEXT: ) |
| (func $same-sig-suspending (type $sig-unary) (param $x i32) (result i32) |
| (suspend $tag-i32 (local.get $x)) |
| (local.get $x) |
| ) |
| |
| ;; NO-TNH: (func $side-effect-1 (type $2) (result i32) |
| ;; NO-TNH-NEXT: (global.set $counter |
| ;; NO-TNH-NEXT: (i32.add |
| ;; NO-TNH-NEXT: (global.get $counter) |
| ;; NO-TNH-NEXT: (i32.const 1) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (i32.const 10) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $side-effect-1 (type $2) (result i32) |
| ;; TNH-NEXT: (global.set $counter |
| ;; TNH-NEXT: (i32.add |
| ;; TNH-NEXT: (global.get $counter) |
| ;; TNH-NEXT: (i32.const 1) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (i32.const 10) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $side-effect-1 (type $2) (result i32) |
| ;; VACUUM-NEXT: (global.set $counter |
| ;; VACUUM-NEXT: (i32.add |
| ;; VACUUM-NEXT: (global.get $counter) |
| ;; VACUUM-NEXT: (i32.const 1) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (i32.const 10) |
| ;; VACUUM-NEXT: ) |
| (func $side-effect-1 (result i32) |
| (global.set $counter (i32.add (global.get $counter) (i32.const 1))) |
| (i32.const 10) |
| ) |
| |
| ;; NO-TNH: (func $side-effect-2 (type $2) (result i32) |
| ;; NO-TNH-NEXT: (global.set $counter |
| ;; NO-TNH-NEXT: (i32.add |
| ;; NO-TNH-NEXT: (global.get $counter) |
| ;; NO-TNH-NEXT: (i32.const 2) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (i32.const 20) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $side-effect-2 (type $2) (result i32) |
| ;; TNH-NEXT: (global.set $counter |
| ;; TNH-NEXT: (i32.add |
| ;; TNH-NEXT: (global.get $counter) |
| ;; TNH-NEXT: (i32.const 2) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (i32.const 20) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $side-effect-2 (type $2) (result i32) |
| ;; VACUUM-NEXT: (global.set $counter |
| ;; VACUUM-NEXT: (i32.add |
| ;; VACUUM-NEXT: (global.get $counter) |
| ;; VACUUM-NEXT: (i32.const 2) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (i32.const 20) |
| ;; VACUUM-NEXT: ) |
| (func $side-effect-2 (result i32) |
| (global.set $counter (i32.add (global.get $counter) (i32.const 2))) |
| (i32.const 20) |
| ) |
| |
| ;; NO-TNH: (func $side-effect-3 (type $sig-none) |
| ;; NO-TNH-NEXT: (global.set $counter |
| ;; NO-TNH-NEXT: (i32.add |
| ;; NO-TNH-NEXT: (global.get $counter) |
| ;; NO-TNH-NEXT: (i32.const 3) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $side-effect-3 (type $sig-none) |
| ;; TNH-NEXT: (global.set $counter |
| ;; TNH-NEXT: (i32.add |
| ;; TNH-NEXT: (global.get $counter) |
| ;; TNH-NEXT: (i32.const 3) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $side-effect-3 (type $sig-none) |
| ;; VACUUM-NEXT: (global.set $counter |
| ;; VACUUM-NEXT: (i32.add |
| ;; VACUUM-NEXT: (global.get $counter) |
| ;; VACUUM-NEXT: (i32.const 3) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $side-effect-3 |
| (global.set $counter (i32.add (global.get $counter) (i32.const 3))) |
| ) |
| |
| ;; NO-TNH: (func $test-resume-null (type $sig-none) |
| ;; NO-TNH-NEXT: (unreachable) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-resume-null (type $sig-none) |
| ;; TNH-NEXT: (unreachable) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-resume-null (type $sig-none) |
| ;; VACUUM-NEXT: (unreachable) |
| ;; VACUUM-NEXT: ) |
| (func $test-resume-null |
| ;; Resume of null traps: replaced with unreachable. |
| (resume $cont-none |
| (ref.null $cont-none) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-resume-null-operands (type $sig-none) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (block |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (call $side-effect-1) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (call $side-effect-2) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (unreachable) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-resume-null-operands (type $sig-none) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (block |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (call $side-effect-1) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (call $side-effect-2) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (unreachable) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-resume-null-operands (type $sig-none) |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (block |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (call $side-effect-1) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (call $side-effect-2) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (unreachable) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-resume-null-operands |
| ;; Operands are evaluated and dropped before the null trap. |
| (resume $cont-binary |
| (call $side-effect-1) |
| (call $side-effect-2) |
| (ref.null $cont-binary) |
| ) |
| (drop) |
| ) |
| |
| ;; NO-TNH: (func $test-resume-skip-non-null-cast (type $9) (param $c (ref null $cont-none)) |
| ;; NO-TNH-NEXT: (resume $cont-none |
| ;; NO-TNH-NEXT: (local.get $c) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-resume-skip-non-null-cast (type $9) (param $c (ref null $cont-none)) |
| ;; TNH-NEXT: (resume $cont-none |
| ;; TNH-NEXT: (local.get $c) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-resume-skip-non-null-cast (type $9) (param $c (ref null $cont-none)) |
| ;; VACUUM-NEXT: (resume $cont-none |
| ;; VACUUM-NEXT: (local.get $c) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-resume-skip-non-null-cast (param $c (ref null $cont-none)) |
| ;; Redundant ref.as_non_null on continuation is stripped because resume |
| ;; traps on null. |
| (resume $cont-none |
| (ref.as_non_null |
| (local.get $c) |
| ) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-resume-null-arm-tnh (type $6) (param $cond i32) (param $c (ref $cont-none)) |
| ;; NO-TNH-NEXT: (resume $cont-none |
| ;; NO-TNH-NEXT: (if (result (ref null $cont-none)) |
| ;; NO-TNH-NEXT: (local.get $cond) |
| ;; NO-TNH-NEXT: (then |
| ;; NO-TNH-NEXT: (ref.null nocont) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (else |
| ;; NO-TNH-NEXT: (local.get $c) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-resume-null-arm-tnh (type $6) (param $cond i32) (param $c (ref $cont-none)) |
| ;; TNH-NEXT: (resume $cont-none |
| ;; TNH-NEXT: (block (result (ref $cont-none)) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (local.get $cond) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (local.get $c) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-resume-null-arm-tnh (type $6) (param $cond i32) (param $c (ref $cont-none)) |
| ;; VACUUM-NEXT: (resume $cont-none |
| ;; VACUUM-NEXT: (if (result (ref null $cont-none)) |
| ;; VACUUM-NEXT: (local.get $cond) |
| ;; VACUUM-NEXT: (then |
| ;; VACUUM-NEXT: (ref.null nocont) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (else |
| ;; VACUUM-NEXT: (local.get $c) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-resume-null-arm-tnh (param $cond i32) (param $c (ref $cont-none)) |
| ;; Under TNH, if-arms that flow out null are assumed never taken. |
| (resume $cont-none |
| (if (result (ref null $cont-none)) |
| (local.get $cond) |
| (then |
| (ref.null $cont-none) |
| ) |
| (else |
| (local.get $c) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-resume-null-select-tnh (type $6) (param $cond i32) (param $c (ref $cont-none)) |
| ;; NO-TNH-NEXT: (resume $cont-none |
| ;; NO-TNH-NEXT: (select (result (ref null $cont-none)) |
| ;; NO-TNH-NEXT: (ref.null nocont) |
| ;; NO-TNH-NEXT: (local.get $c) |
| ;; NO-TNH-NEXT: (local.get $cond) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-resume-null-select-tnh (type $6) (param $cond i32) (param $c (ref $cont-none)) |
| ;; TNH-NEXT: (resume $cont-none |
| ;; TNH-NEXT: (block (result (ref $cont-none)) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (ref.null nocont) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (block (result (ref $cont-none)) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (local.get $cond) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (local.get $c) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-resume-null-select-tnh (type $6) (param $cond i32) (param $c (ref $cont-none)) |
| ;; VACUUM-NEXT: (resume $cont-none |
| ;; VACUUM-NEXT: (select (result (ref null $cont-none)) |
| ;; VACUUM-NEXT: (ref.null nocont) |
| ;; VACUUM-NEXT: (local.get $c) |
| ;; VACUUM-NEXT: (local.get $cond) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-resume-null-select-tnh (param $cond i32) (param $c (ref $cont-none)) |
| ;; Under TNH, select branches that flow out null are assumed never taken. |
| (resume $cont-none |
| (select (result (ref null $cont-none)) |
| (ref.null $cont-none) |
| (local.get $c) |
| (local.get $cond) |
| ) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-basic (type $sig-none) |
| ;; NO-TNH-NEXT: (call $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-basic (type $sig-none) |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-basic (type $sig-none) |
| ;; VACUUM-NEXT: (nop) |
| ;; VACUUM-NEXT: ) |
| (func $test-basic |
| ;; Basic rewrite: resume of non-suspending continuation becomes direct |
| ;; call. |
| (resume $cont-none |
| (cont.new $cont-none (ref.func $pure)) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-binary (type $2) (result i32) |
| ;; NO-TNH-NEXT: (call $pure-binary |
| ;; NO-TNH-NEXT: (i32.const 1) |
| ;; NO-TNH-NEXT: (i32.const 2) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-binary (type $2) (result i32) |
| ;; TNH-NEXT: (call $pure-binary |
| ;; TNH-NEXT: (i32.const 1) |
| ;; TNH-NEXT: (i32.const 2) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-binary (type $2) (result i32) |
| ;; VACUUM-NEXT: (call $pure-binary |
| ;; VACUUM-NEXT: (i32.const 1) |
| ;; VACUUM-NEXT: (i32.const 2) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-binary (result i32) |
| ;; Operands and results: passed cleanly to the direct call. |
| (resume $cont-binary |
| (i32.const 1) |
| (i32.const 2) |
| (cont.new $cont-binary (ref.func $pure-binary)) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-fallthrough-block (type $sig-none) |
| ;; NO-TNH-NEXT: (call $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-fallthrough-block (type $sig-none) |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-fallthrough-block (type $sig-none) |
| ;; VACUUM-NEXT: (nop) |
| ;; VACUUM-NEXT: ) |
| (func $test-fallthrough-block |
| ;; Fallthrough cases: straight-line blocks and ref.cast. |
| (resume $cont-none |
| (block (result (ref $cont-none)) |
| (cont.new $cont-none |
| (block (result (ref $sig-none)) |
| (ref.func $pure) |
| ) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-fallthrough-cast (type $sig-none) |
| ;; NO-TNH-NEXT: (call $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-fallthrough-cast (type $sig-none) |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-fallthrough-cast (type $sig-none) |
| ;; VACUUM-NEXT: (nop) |
| ;; VACUUM-NEXT: ) |
| (func $test-fallthrough-cast |
| (resume $cont-none |
| (cont.new $cont-none |
| (ref.cast (ref $sig-none) |
| (ref.func $pure) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-tee (type $10) (result (ref $cont-none)) |
| ;; NO-TNH-NEXT: (local $c (ref null $cont-none)) |
| ;; NO-TNH-NEXT: (resume $cont-none |
| ;; NO-TNH-NEXT: (local.tee $c |
| ;; NO-TNH-NEXT: (cont.new $cont-none |
| ;; NO-TNH-NEXT: (ref.func $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (ref.as_non_null |
| ;; NO-TNH-NEXT: (local.get $c) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-tee (type $10) (result (ref $cont-none)) |
| ;; TNH-NEXT: (local $c (ref null $cont-none)) |
| ;; TNH-NEXT: (local $1 (ref null $cont-none)) |
| ;; TNH-NEXT: (block |
| ;; TNH-NEXT: (local.set $1 |
| ;; TNH-NEXT: (local.tee $c |
| ;; TNH-NEXT: (cont.new $cont-none |
| ;; TNH-NEXT: (ref.func $pure) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (ref.as_non_null |
| ;; TNH-NEXT: (local.get $c) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-tee (type $10) (result (ref $cont-none)) |
| ;; VACUUM-NEXT: (local $c (ref null $cont-none)) |
| ;; VACUUM-NEXT: (resume $cont-none |
| ;; VACUUM-NEXT: (local.tee $c |
| ;; VACUUM-NEXT: (cont.new $cont-none |
| ;; VACUUM-NEXT: (ref.func $pure) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (ref.as_non_null |
| ;; VACUUM-NEXT: (local.get $c) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-tee (result (ref $cont-none)) |
| ;; trapsNeverHappen: local.tee is only looked through with TNH. |
| (local $c (ref null $cont-none)) |
| (resume $cont-none |
| (local.tee $c |
| (cont.new $cont-none (ref.func $pure)) |
| ) |
| ) |
| (ref.as_non_null (local.get $c)) |
| ) |
| |
| ;; NO-TNH: (func $test-tee-params (type $11) (result (ref $cont-binary)) |
| ;; NO-TNH-NEXT: (local $c (ref null $cont-binary)) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (resume $cont-binary |
| ;; NO-TNH-NEXT: (i32.const 1) |
| ;; NO-TNH-NEXT: (i32.const 2) |
| ;; NO-TNH-NEXT: (local.tee $c |
| ;; NO-TNH-NEXT: (cont.new $cont-binary |
| ;; NO-TNH-NEXT: (ref.func $pure-binary) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (ref.as_non_null |
| ;; NO-TNH-NEXT: (local.get $c) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-tee-params (type $11) (result (ref $cont-binary)) |
| ;; TNH-NEXT: (local $c (ref null $cont-binary)) |
| ;; TNH-NEXT: (local $1 (ref null $cont-binary)) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (block (result i32) |
| ;; TNH-NEXT: (local.set $1 |
| ;; TNH-NEXT: (local.tee $c |
| ;; TNH-NEXT: (cont.new $cont-binary |
| ;; TNH-NEXT: (ref.func $pure-binary) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (call $pure-binary |
| ;; TNH-NEXT: (i32.const 1) |
| ;; TNH-NEXT: (i32.const 2) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (ref.as_non_null |
| ;; TNH-NEXT: (local.get $c) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-tee-params (type $11) (result (ref $cont-binary)) |
| ;; VACUUM-NEXT: (local $c (ref null $cont-binary)) |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (resume $cont-binary |
| ;; VACUUM-NEXT: (i32.const 1) |
| ;; VACUUM-NEXT: (i32.const 2) |
| ;; VACUUM-NEXT: (local.tee $c |
| ;; VACUUM-NEXT: (cont.new $cont-binary |
| ;; VACUUM-NEXT: (ref.func $pure-binary) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (ref.as_non_null |
| ;; VACUUM-NEXT: (local.get $c) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-tee-params (result (ref $cont-binary)) |
| ;; trapsNeverHappen: local.tee with operands is only looked through with |
| ;; TNH. |
| (local $c (ref null $cont-binary)) |
| (drop |
| (resume $cont-binary |
| (i32.const 1) |
| (i32.const 2) |
| (local.tee $c |
| (cont.new $cont-binary (ref.func $pure-binary)) |
| ) |
| ) |
| ) |
| (ref.as_non_null (local.get $c)) |
| ) |
| |
| ;; NO-TNH: (func $test-tee-func (type $12) (result (ref $sig-none)) |
| ;; NO-TNH-NEXT: (local $f (ref null $sig-none)) |
| ;; NO-TNH-NEXT: (local $1 (ref (exact $cont-none))) |
| ;; NO-TNH-NEXT: (block |
| ;; NO-TNH-NEXT: (local.set $1 |
| ;; NO-TNH-NEXT: (cont.new $cont-none |
| ;; NO-TNH-NEXT: (local.tee $f |
| ;; NO-TNH-NEXT: (ref.func $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (call $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (ref.as_non_null |
| ;; NO-TNH-NEXT: (local.get $f) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-tee-func (type $12) (result (ref $sig-none)) |
| ;; TNH-NEXT: (local $f (ref null $sig-none)) |
| ;; TNH-NEXT: (local $1 (ref (exact $cont-none))) |
| ;; TNH-NEXT: (block |
| ;; TNH-NEXT: (local.set $1 |
| ;; TNH-NEXT: (cont.new $cont-none |
| ;; TNH-NEXT: (local.tee $f |
| ;; TNH-NEXT: (ref.func $pure) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (ref.as_non_null |
| ;; TNH-NEXT: (local.get $f) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-tee-func (type $12) (result (ref $sig-none)) |
| ;; VACUUM-NEXT: (local $f (ref null $sig-none)) |
| ;; VACUUM-NEXT: (local $1 (ref (exact $cont-none))) |
| ;; VACUUM-NEXT: (local.set $1 |
| ;; VACUUM-NEXT: (cont.new $cont-none |
| ;; VACUUM-NEXT: (local.tee $f |
| ;; VACUUM-NEXT: (ref.func $pure) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (ref.as_non_null |
| ;; VACUUM-NEXT: (local.get $f) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-tee-func (result (ref $sig-none)) |
| ;; Now the tee is on the ref.func. We can look through it with or without |
| ;; TNH. |
| (local $f (ref null $sig-none)) |
| (resume $cont-none |
| (cont.new $cont-none |
| (local.tee $f (ref.func $pure)) |
| ) |
| ) |
| (ref.as_non_null (local.get $f)) |
| ) |
| |
| ;; NO-TNH: (func $test-negative-suspend (type $sig-none) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (block $on-suspend (result (ref $cont-none)) |
| ;; NO-TNH-NEXT: (resume $cont-none (on $tag $on-suspend) |
| ;; NO-TNH-NEXT: (cont.new $cont-none |
| ;; NO-TNH-NEXT: (ref.func $suspending) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (unreachable) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-negative-suspend (type $sig-none) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (block $on-suspend (result (ref $cont-none)) |
| ;; TNH-NEXT: (resume $cont-none (on $tag $on-suspend) |
| ;; TNH-NEXT: (cont.new $cont-none |
| ;; TNH-NEXT: (ref.func $suspending) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (unreachable) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-negative-suspend (type $sig-none) |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (block $on-suspend (result (ref $cont-none)) |
| ;; VACUUM-NEXT: (resume $cont-none (on $tag $on-suspend) |
| ;; VACUUM-NEXT: (cont.new $cont-none |
| ;; VACUUM-NEXT: (ref.func $suspending) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (unreachable) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-negative-suspend |
| ;; Negative test: continuation function that suspends cannot be converted. |
| (block $on-suspend (result (ref $cont-none)) |
| (resume $cont-none (on $tag $on-suspend) |
| (cont.new $cont-none (ref.func $suspending)) |
| ) |
| (unreachable) |
| ) |
| (drop) |
| ) |
| |
| ;; NO-TNH: (func $test-negative-transitive-suspend (type $sig-none) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (block $on-suspend (result (ref $cont-none)) |
| ;; NO-TNH-NEXT: (resume $cont-none (on $tag $on-suspend) |
| ;; NO-TNH-NEXT: (cont.new $cont-none |
| ;; NO-TNH-NEXT: (ref.func $caller-of-suspending) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (unreachable) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-negative-transitive-suspend (type $sig-none) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (block $on-suspend (result (ref $cont-none)) |
| ;; TNH-NEXT: (resume $cont-none (on $tag $on-suspend) |
| ;; TNH-NEXT: (cont.new $cont-none |
| ;; TNH-NEXT: (ref.func $caller-of-suspending) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (unreachable) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-negative-transitive-suspend (type $sig-none) |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (block $on-suspend (result (ref $cont-none)) |
| ;; VACUUM-NEXT: (resume $cont-none (on $tag $on-suspend) |
| ;; VACUUM-NEXT: (cont.new $cont-none |
| ;; VACUUM-NEXT: (ref.func $caller-of-suspending) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (unreachable) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-negative-transitive-suspend |
| ;; Negative test: continuation function calling a suspending function. |
| (block $on-suspend (result (ref $cont-none)) |
| (resume $cont-none (on $tag $on-suspend) |
| (cont.new $cont-none (ref.func $caller-of-suspending)) |
| ) |
| (unreachable) |
| ) |
| (drop) |
| ) |
| |
| ;; NO-TNH: (func $test-same-sig (type $2) (result i32) |
| ;; NO-TNH-NEXT: (call $same-sig-pure |
| ;; NO-TNH-NEXT: (i32.const 42) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-same-sig (type $2) (result i32) |
| ;; TNH-NEXT: (call $same-sig-pure |
| ;; TNH-NEXT: (i32.const 42) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-same-sig (type $2) (result i32) |
| ;; VACUUM-NEXT: (call $same-sig-pure |
| ;; VACUUM-NEXT: (i32.const 42) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-same-sig (result i32) |
| ;; Precision test: function $f does not suspend, but another function with |
| ;; the same signature does. Verify $f is still converted. |
| (resume $cont-unary |
| (i32.const 42) |
| (cont.new $cont-unary (ref.func $same-sig-pure)) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-eval-order (type $2) (result i32) |
| ;; NO-TNH-NEXT: (local $0 i32) |
| ;; NO-TNH-NEXT: (local $1 i32) |
| ;; NO-TNH-NEXT: (local $2 (ref $cont-binary)) |
| ;; NO-TNH-NEXT: (local.set $0 |
| ;; NO-TNH-NEXT: (call $side-effect-1) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (local.set $1 |
| ;; NO-TNH-NEXT: (call $side-effect-2) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (local.set $2 |
| ;; NO-TNH-NEXT: (block (result (ref $cont-binary)) |
| ;; NO-TNH-NEXT: (call $side-effect-3) |
| ;; NO-TNH-NEXT: (cont.new $cont-binary |
| ;; NO-TNH-NEXT: (ref.func $pure-binary) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (call $pure-binary |
| ;; NO-TNH-NEXT: (local.get $0) |
| ;; NO-TNH-NEXT: (local.get $1) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-eval-order (type $2) (result i32) |
| ;; TNH-NEXT: (local $0 i32) |
| ;; TNH-NEXT: (local $1 i32) |
| ;; TNH-NEXT: (local $2 (ref $cont-binary)) |
| ;; TNH-NEXT: (local.set $0 |
| ;; TNH-NEXT: (call $side-effect-1) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (local.set $1 |
| ;; TNH-NEXT: (call $side-effect-2) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (local.set $2 |
| ;; TNH-NEXT: (block (result (ref $cont-binary)) |
| ;; TNH-NEXT: (call $side-effect-3) |
| ;; TNH-NEXT: (cont.new $cont-binary |
| ;; TNH-NEXT: (ref.func $pure-binary) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (call $pure-binary |
| ;; TNH-NEXT: (local.get $0) |
| ;; TNH-NEXT: (local.get $1) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-eval-order (type $2) (result i32) |
| ;; VACUUM-NEXT: (local $0 i32) |
| ;; VACUUM-NEXT: (local $1 i32) |
| ;; VACUUM-NEXT: (local $2 (ref $cont-binary)) |
| ;; VACUUM-NEXT: (local.set $0 |
| ;; VACUUM-NEXT: (call $side-effect-1) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (local.set $1 |
| ;; VACUUM-NEXT: (call $side-effect-2) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (local.set $2 |
| ;; VACUUM-NEXT: (block (result (ref (exact $cont-binary))) |
| ;; VACUUM-NEXT: (call $side-effect-3) |
| ;; VACUUM-NEXT: (cont.new $cont-binary |
| ;; VACUUM-NEXT: (ref.func $pure-binary) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (call $pure-binary |
| ;; VACUUM-NEXT: (local.get $0) |
| ;; VACUUM-NEXT: (local.get $1) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-eval-order (result i32) |
| ;; Evaluation order test: side effects in continuation expression execute |
| ;; after operands and before the direct call. |
| (resume $cont-binary |
| (call $side-effect-1) |
| (call $side-effect-2) |
| (block (result (ref $cont-binary)) |
| (call $side-effect-3) |
| (cont.new $cont-binary (ref.func $pure-binary)) |
| ) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-handler-elimination (type $sig-none) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (block $handler (result (ref $cont-none)) |
| ;; NO-TNH-NEXT: (block |
| ;; NO-TNH-NEXT: (call $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (return) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-handler-elimination (type $sig-none) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (block $handler (result (ref $cont-none)) |
| ;; TNH-NEXT: (block |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (return) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-handler-elimination (type $sig-none) |
| ;; VACUUM-NEXT: (nop) |
| ;; VACUUM-NEXT: ) |
| (func $test-handler-elimination |
| ;; Handler elimination test: dead handler blocks are removed in full |
| ;; pipeline. |
| (block $handler (result (ref $cont-none)) |
| (resume $cont-none (on $tag $handler) |
| (cont.new $cont-none (ref.func $pure)) |
| ) |
| (return) |
| ) |
| (drop) |
| ) |
| |
| ;; NO-TNH: (func $test-unreachable-operand (type $sig-none) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (resume $cont-binary |
| ;; NO-TNH-NEXT: (unreachable) |
| ;; NO-TNH-NEXT: (i32.const 1) |
| ;; NO-TNH-NEXT: (cont.new $cont-binary |
| ;; NO-TNH-NEXT: (ref.func $pure-binary) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-unreachable-operand (type $sig-none) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (resume $cont-binary |
| ;; TNH-NEXT: (unreachable) |
| ;; TNH-NEXT: (i32.const 1) |
| ;; TNH-NEXT: (cont.new $cont-binary |
| ;; TNH-NEXT: (ref.func $pure-binary) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-unreachable-operand (type $sig-none) |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (resume $cont-binary |
| ;; VACUUM-NEXT: (unreachable) |
| ;; VACUUM-NEXT: (i32.const 1) |
| ;; VACUUM-NEXT: (cont.new $cont-binary |
| ;; VACUUM-NEXT: (ref.func $pure-binary) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-unreachable-operand |
| ;; Unreachable operands or continuation: resume is unreachable, left for |
| ;; DCE. |
| (resume $cont-binary |
| (unreachable) |
| (i32.const 1) |
| (cont.new $cont-binary (ref.func $pure-binary)) |
| ) |
| (drop) |
| ) |
| |
| ;; NO-TNH: (func $test-unreachable-cont (type $sig-none) |
| ;; NO-TNH-NEXT: (block ;; (replaces unreachable Resume we can't emit) |
| ;; NO-TNH-NEXT: (drop |
| ;; NO-TNH-NEXT: (unreachable) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (unreachable) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-unreachable-cont (type $sig-none) |
| ;; TNH-NEXT: (block ;; (replaces unreachable Resume we can't emit) |
| ;; TNH-NEXT: (drop |
| ;; TNH-NEXT: (unreachable) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (unreachable) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-unreachable-cont (type $sig-none) |
| ;; VACUUM-NEXT: (block ;; (replaces unreachable Resume we can't emit) |
| ;; VACUUM-NEXT: (drop |
| ;; VACUUM-NEXT: (unreachable) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: (unreachable) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-unreachable-cont |
| ;; Unreachable continuation: resume is unreachable, left for DCE. |
| (resume $cont-none |
| (unreachable) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-negative-imported (type $sig-none) |
| ;; NO-TNH-NEXT: (resume $cont-none |
| ;; NO-TNH-NEXT: (cont.new $cont-none |
| ;; NO-TNH-NEXT: (ref.func $imported) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-negative-imported (type $sig-none) |
| ;; TNH-NEXT: (resume $cont-none |
| ;; TNH-NEXT: (cont.new $cont-none |
| ;; TNH-NEXT: (ref.func $imported) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-negative-imported (type $sig-none) |
| ;; VACUUM-NEXT: (resume $cont-none |
| ;; VACUUM-NEXT: (cont.new $cont-none |
| ;; VACUUM-NEXT: (ref.func $imported) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-negative-imported |
| ;; Negative test: continuation function is imported and cannot be proven |
| ;; non-suspending. |
| (resume $cont-none |
| (cont.new $cont-none (ref.func $imported)) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-handler-switch (type $sig-none) |
| ;; NO-TNH-NEXT: (call $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-handler-switch (type $sig-none) |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-handler-switch (type $sig-none) |
| ;; VACUUM-NEXT: (nop) |
| ;; VACUUM-NEXT: ) |
| (func $test-handler-switch |
| ;; Handler elimination test: switch handlers are also eliminated when |
| ;; directizing. |
| (resume $cont-none (on $tag switch) |
| (cont.new $cont-none (ref.func $pure)) |
| ) |
| ) |
| |
| ;; NO-TNH: (func $test-eval-order-no-operands (type $sig-none) |
| ;; NO-TNH-NEXT: (local $0 (ref $cont-none)) |
| ;; NO-TNH-NEXT: (local.set $0 |
| ;; NO-TNH-NEXT: (block (result (ref $cont-none)) |
| ;; NO-TNH-NEXT: (call $side-effect-3) |
| ;; NO-TNH-NEXT: (cont.new $cont-none |
| ;; NO-TNH-NEXT: (ref.func $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: ) |
| ;; NO-TNH-NEXT: (call $pure) |
| ;; NO-TNH-NEXT: ) |
| ;; TNH: (func $test-eval-order-no-operands (type $sig-none) |
| ;; TNH-NEXT: (local $0 (ref $cont-none)) |
| ;; TNH-NEXT: (local.set $0 |
| ;; TNH-NEXT: (block (result (ref $cont-none)) |
| ;; TNH-NEXT: (call $side-effect-3) |
| ;; TNH-NEXT: (cont.new $cont-none |
| ;; TNH-NEXT: (ref.func $pure) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: ) |
| ;; TNH-NEXT: (call $pure) |
| ;; TNH-NEXT: ) |
| ;; VACUUM: (func $test-eval-order-no-operands (type $sig-none) |
| ;; VACUUM-NEXT: (local $0 (ref $cont-none)) |
| ;; VACUUM-NEXT: (local.set $0 |
| ;; VACUUM-NEXT: (block (result (ref (exact $cont-none))) |
| ;; VACUUM-NEXT: (call $side-effect-3) |
| ;; VACUUM-NEXT: (cont.new $cont-none |
| ;; VACUUM-NEXT: (ref.func $pure) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| ;; VACUUM-NEXT: ) |
| (func $test-eval-order-no-operands |
| ;; Evaluation order test: side effects in continuation expression execute |
| ;; before the direct call even when there are no operands. |
| (resume $cont-none |
| (block (result (ref $cont-none)) |
| (call $side-effect-3) |
| (cont.new $cont-none (ref.func $pure)) |
| ) |
| ) |
| ) |
| ) |