diff options
Diffstat (limited to 'test/lit')
-rw-r--r-- | test/lit/passes/coalesce-locals-learning.wast | 1766 | ||||
-rw-r--r-- | test/lit/passes/coalesce-locals.wast | 2511 | ||||
-rw-r--r-- | test/lit/passes/code-folding_enable-threads.wast | 433 | ||||
-rw-r--r-- | test/lit/passes/code-pushing_ignore-implicit-traps.wast | 715 | ||||
-rw-r--r-- | test/lit/passes/const-hoisting.wast | 834 |
5 files changed, 6259 insertions, 0 deletions
diff --git a/test/lit/passes/coalesce-locals-learning.wast b/test/lit/passes/coalesce-locals-learning.wast new file mode 100644 index 000000000..af1c7d560 --- /dev/null +++ b/test/lit/passes/coalesce-locals-learning.wast @@ -0,0 +1,1766 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; NOTE: This test was ported using port_test.py and could be cleaned up. + +;; RUN: foreach %s %t wasm-opt --coalesce-locals-learning -S -o - | filecheck %s + +(module + (memory 10) + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + + ;; CHECK: (type $3 (func (param i32 f32))) + + ;; CHECK: (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $2 (func)) + (type $3 (func (param i32 f32))) + ;; CHECK: (type $4 (func (param i32))) + (type $4 (func (param i32))) + (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32)) + ;; CHECK: (import "env" "_emscripten_autodebug_i32" (func $_emscripten_autodebug_i32 (param i32 i32) (result i32))) + + ;; CHECK: (memory $0 10) + + ;; CHECK: (func $nothing-to-do + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $nothing-to-do (type $2) + (local $x i32) + (nop) + ) + ;; CHECK: (func $merge + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $merge (type $2) + (local $x i32) + (local $y i32) + (nop) + ) + ;; CHECK: (func $leave-type + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $leave-type (type $2) + (local $x i32) + (local $y f32) + (nop) + ) + ;; CHECK: (func $leave-interfere + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $leave-interfere (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 0) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $almost-interfere + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $almost-interfere (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + (local.set $y + (i32.const 0) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $redundant-copy + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $redundant-copy (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $ineffective-store + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ineffective-store (type $2) + (local $x i32) + (local.set $x + (i32.const 0) + ) + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $block + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block0 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $block (type $2) + (local $x i32) + (block $block0 + (local.set $x + (i32.const 0) + ) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $see-both-sides + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block0 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $see-both-sides (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (block $block0 + (local.set $y + (i32.const 0) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $see-br-and-ignore-dead + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (br $block) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $see-br-and-ignore-dead (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (block $block + (br $block) + (local.set $y + (i32.const 0) + ) + (drop + (local.get $y) + ) + (local.set $x + (i32.const -1) + ) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $see-block-body + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $block) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $see-block-body (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (block $block + (local.set $y + (i32.const 0) + ) + (drop + (local.get $y) + ) + (br $block) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $zero-init + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $zero-init (type $2) + (local $x i32) + (local $y i32) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $multi + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $multi (type $2) + (local $x i32) + (local $y i32) + (local $z i32) + (drop + (local.get $y) + ) + (drop + (local.get $z) + ) + ) + ;; CHECK: (func $if-else + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $if-else-parallel + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else-parallel (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + ) + (block $block3 + (local.set $y + (i32.const 1) + ) + (drop + (local.get $y) + ) + ) + ) + ) + ;; CHECK: (func $if-else-after + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else-after (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 1) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-else-through + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else-through (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 1) + ) + (if + (i32.const 0) + (drop + (i32.const 1) + ) + (drop + (i32.const 2) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-through + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-through (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 1) + ) + (if + (i32.const 0) + (drop + (i32.const 1) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-through2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-through2 (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (if + (i32.const 0) + (local.set $y + (i32.const 1) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-through3 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-through3 (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (if + (i32.const 0) + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ) + ;; CHECK: (func $if2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if2 (type $2) + (local $x i32) + (local $y i32) + (if + (local.tee $x + (i32.const 0) + ) + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ) + ;; CHECK: (func $if3 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if3 (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + ) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if4 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if4 (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) + ) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if5 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if5 (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) + ) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $loop + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (loop $in + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $in) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $loop (type $2) + (local $x i32) + (local $y i32) + (block $out + (loop $in + (drop + (local.get $x) + ) + (local.set $x + (i32.const 0) + ) + (drop + (local.get $y) + ) + (br $in) + ) + ) + ) + ;; CHECK: (func $interfere-in-dead + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (br $block) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead (type $2) + (local $x i32) + (local $y i32) + (block $block + (br $block) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $interfere-in-dead2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead2 (type $2) + (local $x i32) + (local $y i32) + (block $block + (unreachable) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $interfere-in-dead3 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead3 (type $2) + (local $x i32) + (local $y i32) + (block $block + (return) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $params (param $0 i32) (param $1 f32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $params (type $3) (param $p i32) (param $q f32) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (drop + (local.get $y) + ) + (drop + (local.get $z) + ) + (drop + (local.get $w) + ) + ) + ;; CHECK: (func $interfere-in-dead4 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (br_if $block + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead4 (type $2) + (local $x i32) + (local $y i32) + (block $block + (br_if $block + (i32.const 0) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $switch + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (block $switch$def + ;; CHECK-NEXT: (block $switch-case$1 + ;; CHECK-NEXT: (block $switch-case$2 + ;; CHECK-NEXT: (br_table $switch-case$1 $switch-case$2 $switch-case$1 $switch-case$1 $switch$def + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $switch (type $2) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (block $switch$def + (block $switch-case$1 + (block $switch-case$2 + (br_table $switch-case$1 $switch-case$2 $switch-case$1 $switch-case$1 $switch$def + (i32.const 100) + ) + (drop + (local.get $x) + ) + ) + (drop + (local.get $y) + ) + ) + (drop + (local.get $z) + ) + ) + (drop + (local.get $w) + ) + ) + ;; CHECK: (func $greedy-can-be-happy + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $greedy-can-be-happy (type $2) + (local $x1 i32) + (local $x2 i32) + (local $x3 i32) + (local $y1 i32) + (local $y2 i32) + (local $y3 i32) + (if + (i32.const 0) + (if + (i32.const 1) + (if + (i32.const 2) + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) + (if + (i32.const 3) + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) + ) + (if + (i32.const 4) + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) + ) + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) + ) + ) + ) + ) + ;; CHECK: (func $greedy-can-be-sad + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $greedy-can-be-sad (type $2) + (local $x1 i32) + (local $y1 i32) + (local $x2 i32) + (local $y2 i32) + (local $x3 i32) + (local $y3 i32) + (if + (i32.const 0) + (if + (i32.const 1) + (if + (i32.const 2) + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) + (if + (i32.const 3) + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) + ) + (if + (i32.const 4) + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) + ) + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) + ) + ) + ) + ) + ;; CHECK: (func $_memcpy (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4096) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block2 + ;; CHECK-NEXT: (block $while-out$0 + ;; CHECK-NEXT: (loop $while-in$1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $while-out$2 + ;; CHECK-NEXT: (loop $while-in$3 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out$2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block7 + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $while-out$4 + ;; CHECK-NEXT: (loop $while-in$5 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out$4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block9 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $_memcpy (type $FUNCSIG$iiii) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) + (local $i4 i32) + (if + (i32.ge_s + (local.get $i3) + (i32.const 4096) + ) + (drop + (local.get $i1) + ) + ) + (local.set $i4 + (local.get $i1) + ) + (if + (i32.eq + (i32.and + (local.get $i1) + (i32.const 3) + ) + (i32.and + (local.get $i2) + (i32.const 3) + ) + ) + (block $block2 + (block $while-out$0 + (loop $while-in$1 + (if + (i32.eqz + (i32.and + (local.get $i1) + (i32.const 3) + ) + ) + (br $while-out$0) + ) + (block $block4 + (if + (i32.eqz + (local.get $i3) + ) + (return + (local.get $i4) + ) + ) + (i32.store8 + (local.get $i1) + (i32.load8_s + (local.get $i2) + ) + ) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 1) + ) + ) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 1) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 1) + ) + ) + ) + (br $while-in$1) + ) + ) + (block $while-out$2 + (loop $while-in$3 + (if + (i32.eqz + (i32.ge_s + (local.get $i3) + (i32.const 4) + ) + ) + (br $while-out$2) + ) + (block $block7 + (i32.store + (local.get $i1) + (i32.load + (local.get $i2) + ) + ) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 4) + ) + ) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 4) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 4) + ) + ) + ) + (br $while-in$3) + ) + ) + ) + ) + (block $while-out$4 + (loop $while-in$5 + (if + (i32.eqz + (i32.gt_s + (local.get $i3) + (i32.const 0) + ) + ) + (br $while-out$4) + ) + (block $block9 + (i32.store8 + (local.get $i1) + (i32.load8_s + (local.get $i2) + ) + ) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 1) + ) + ) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 1) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 1) + ) + ) + ) + (br $while-in$5) + ) + ) + (return + (local.get $i4) + ) + ) + ;; CHECK: (func $this-is-effective-i-tell-you (param $0 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $this-is-effective-i-tell-you (type $4) (param $x i32) + (if + (i32.const -1) + (block $block1 + (if + (i32.const 0) + (nop) + ) + (local.set $x + (i32.const 1) + ) + ) + (nop) + ) + (drop + (local.get $x) + ) + ) +) diff --git a/test/lit/passes/coalesce-locals.wast b/test/lit/passes/coalesce-locals.wast new file mode 100644 index 000000000..343013150 --- /dev/null +++ b/test/lit/passes/coalesce-locals.wast @@ -0,0 +1,2511 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; NOTE: This test was ported using port_test.py and could be cleaned up. + +;; RUN: foreach %s %t wasm-opt --coalesce-locals -S -o - | filecheck %s + +(module + (memory 10) + ;; CHECK: (type $2 (func)) + + ;; CHECK: (type $4 (func (param i32))) + + ;; CHECK: (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + + ;; CHECK: (type $f64_i32_=>_i64 (func (param f64 i32) (result i64))) + + ;; CHECK: (type $none_=>_i32 (func (result i32))) + + ;; CHECK: (type $3 (func (param i32 f32))) + + ;; CHECK: (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $2 (func)) + (type $3 (func (param i32 f32))) + (type $4 (func (param i32))) + (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32)) + (import $get "env" "get" (result i32)) + (import $set "env" "set" (param i32)) + ;; CHECK: (type $i32_=>_i32 (func (param i32) (result i32))) + + ;; CHECK: (type $i32_i32_=>_none (func (param i32 i32))) + + ;; CHECK: (type $none_=>_f64 (func (result f64))) + + ;; CHECK: (import "env" "_emscripten_autodebug_i32" (func $_emscripten_autodebug_i32 (param i32 i32) (result i32))) + + ;; CHECK: (import "env" "get" (func $get (result i32))) + + ;; CHECK: (import "env" "set" (func $set (param i32))) + + ;; CHECK: (memory $0 10) + + ;; CHECK: (func $nothing-to-do + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $nothing-to-do (type $2) + (local $x i32) + (nop) + ) + ;; CHECK: (func $merge + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $merge (type $2) + (local $x i32) + (local $y i32) + (nop) + ) + ;; CHECK: (func $leave-type + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 f32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $leave-type (type $2) + (local $x i32) + (local $y f32) + (nop) + ) + ;; CHECK: (func $leave-interfere + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $leave-interfere (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 0) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $almost-interfere + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $almost-interfere (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + (local.set $y + (i32.const 0) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $redundant-copy + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $redundant-copy (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $ineffective-store + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ineffective-store (type $2) + (local $x i32) + (local.set $x + (i32.const 0) + ) + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $block + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block0 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $block (type $2) + (local $x i32) + (block $block0 + (local.set $x + (i32.const 0) + ) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $see-both-sides + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block0 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $see-both-sides (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (block $block0 + (local.set $y + (i32.const 0) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $see-br-and-ignore-dead + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (br $block) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $see-br-and-ignore-dead (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (block $block + (br $block) + (local.set $y + (i32.const 0) + ) + (drop + (local.get $y) + ) + (local.set $x + (i32.const -1) + ) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $see-block-body + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $block) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $see-block-body (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (block $block + (local.set $y + (i32.const 0) + ) + (drop + (local.get $y) + ) + (br $block) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $zero-init + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $zero-init (type $2) + (local $x i32) + (local $y i32) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $multi + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $multi (type $2) + (local $x i32) + (local $y i32) + (local $z i32) + (drop + (local.get $y) + ) + (drop + (local.get $z) + ) + ) + ;; CHECK: (func $if-else + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $if-else-parallel + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else-parallel (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + ) + (block $block3 + (local.set $y + (i32.const 1) + ) + (drop + (local.get $y) + ) + ) + ) + ) + ;; CHECK: (func $if-else-after + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else-after (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 1) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-else-through + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-else-through (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 1) + ) + (if + (i32.const 0) + (drop + (i32.const 1) + ) + (drop + (i32.const 2) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-through + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-through (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (i32.const 1) + ) + (if + (i32.const 0) + (drop + (i32.const 1) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-through2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-through2 (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (if + (i32.const 0) + (local.set $y + (i32.const 1) + ) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if-through3 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-through3 (type $2) + (local $x i32) + (local $y i32) + (local.set $x + (i32.const 0) + ) + (if + (i32.const 0) + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ) + ;; CHECK: (func $if2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if2 (type $2) + (local $x i32) + (local $y i32) + (if + (local.tee $x + (i32.const 0) + ) + (block $block1 + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ) + ;; CHECK: (func $if3 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if3 (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + ) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if4 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if4 (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (local.set $x + (i32.const 0) + ) + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) + ) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $if5 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if5 (type $2) + (local $x i32) + (local $y i32) + (if + (i32.const 0) + (block $block1 + (drop + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) + ) + ) + (drop + (local.get $y) + ) + ) + ;; CHECK: (func $loop + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $in + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $in) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $loop (type $2) + (local $x i32) + (local $y i32) + (loop $in + (drop + (local.get $x) + ) + (local.set $x + (i32.const 0) + ) + (drop + (local.get $y) + ) + (br $in) + ) + ) + ;; CHECK: (func $interfere-in-dead + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (br $block) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead (type $2) + (local $x i32) + (local $y i32) + (block $block + (br $block) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $interfere-in-dead2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead2 (type $2) + (local $x i32) + (local $y i32) + (block $block + (unreachable) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $interfere-in-dead3 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead3 (type $2) + (local $x i32) + (local $y i32) + (block $block + (return) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $params (param $0 i32) (param $1 f32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $params (type $3) (param $p i32) (param $q f32) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (drop + (local.get $y) + ) + (drop + (local.get $z) + ) + (drop + (local.get $w) + ) + ) + ;; CHECK: (func $interfere-in-dead4 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (br_if $block + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $interfere-in-dead4 (type $2) + (local $x i32) + (local $y i32) + (block $block + (br_if $block + (i32.const 0) + ) + (drop + (local.get $x) + ) + (drop + (local.get $y) + ) + ) + ) + ;; CHECK: (func $switch + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (block $switch$def + ;; CHECK-NEXT: (block $switch-case$1 + ;; CHECK-NEXT: (block $switch-case$2 + ;; CHECK-NEXT: (br_table $switch-case$1 $switch-case$2 $switch-case$1 $switch-case$1 $switch$def + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $switch (type $2) + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (block $switch$def + (block $switch-case$1 + (block $switch-case$2 + (br_table $switch-case$1 $switch-case$2 $switch-case$1 $switch-case$1 $switch$def + (i32.const 100) + ) + (drop + (local.get $x) + ) + ) + (drop + (local.get $y) + ) + ) + (drop + (local.get $z) + ) + ) + (drop + (local.get $w) + ) + ) + ;; CHECK: (func $greedy-can-be-happy + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $greedy-can-be-happy (type $2) + (local $x1 i32) + (local $x2 i32) + (local $x3 i32) + (local $y1 i32) + (local $y2 i32) + (local $y3 i32) + (if + (i32.const 0) + (if + (i32.const 1) + (if + (i32.const 2) + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) + (if + (i32.const 3) + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) + ) + (if + (i32.const 4) + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) + ) + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) + ) + ) + ) + ) + ;; CHECK: (func $greedy-can-be-sad + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (block $block3 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 101) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block5 + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 102) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 103) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (block $block8 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 104) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block10 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 106) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 107) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: (block $block13 + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 108) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 109) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block15 + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 110) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 111) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $greedy-can-be-sad (type $2) + (local $x1 i32) + (local $y1 i32) + (local $x2 i32) + (local $y2 i32) + (local $x3 i32) + (local $y3 i32) + (if + (i32.const 0) + (if + (i32.const 1) + (if + (i32.const 2) + (block $block3 + (local.set $x1 + (i32.const 100) + ) + (local.set $y2 + (i32.const 101) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y2) + ) + ) + (block $block5 + (local.set $x1 + (i32.const 102) + ) + (local.set $y3 + (i32.const 103) + ) + (drop + (local.get $x1) + ) + (drop + (local.get $y3) + ) + ) + ) + (if + (i32.const 3) + (block $block8 + (local.set $x2 + (i32.const 104) + ) + (local.set $y1 + (i32.const 105) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y1) + ) + ) + (block $block10 + (local.set $x2 + (i32.const 106) + ) + (local.set $y3 + (i32.const 107) + ) + (drop + (local.get $x2) + ) + (drop + (local.get $y3) + ) + ) + ) + ) + (if + (i32.const 4) + (block $block13 + (local.set $x3 + (i32.const 108) + ) + (local.set $y1 + (i32.const 109) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y1) + ) + ) + (block $block15 + (local.set $x3 + (i32.const 110) + ) + (local.set $y2 + (i32.const 111) + ) + (drop + (local.get $x3) + ) + (drop + (local.get $y2) + ) + ) + ) + ) + ) + ;; CHECK: (func $_memcpy (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4096) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block2 + ;; CHECK-NEXT: (block $while-out$0 + ;; CHECK-NEXT: (loop $while-in$1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.and + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $while-out$2 + ;; CHECK-NEXT: (loop $while-in$3 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.ge_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out$2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block7 + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $while-out$4 + ;; CHECK-NEXT: (loop $while-in$5 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eqz + ;; CHECK-NEXT: (i32.gt_s + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-out$4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block9 + ;; CHECK-NEXT: (i32.store8 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.load8_s + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $while-in$5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $_memcpy (type $FUNCSIG$iiii) (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32) + (local $i4 i32) + (if + (i32.ge_s + (local.get $i3) + (i32.const 4096) + ) + (drop + (local.get $i1) + ) + ) + (local.set $i4 + (local.get $i1) + ) + (if + (i32.eq + (i32.and + (local.get $i1) + (i32.const 3) + ) + (i32.and + (local.get $i2) + (i32.const 3) + ) + ) + (block $block2 + (block $while-out$0 + (loop $while-in$1 + (if + (i32.eqz + (i32.and + (local.get $i1) + (i32.const 3) + ) + ) + (br $while-out$0) + ) + (block $block4 + (if + (i32.eqz + (local.get $i3) + ) + (return + (local.get $i4) + ) + ) + (i32.store8 + (local.get $i1) + (i32.load8_s + (local.get $i2) + ) + ) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 1) + ) + ) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 1) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 1) + ) + ) + ) + (br $while-in$1) + ) + ) + (block $while-out$2 + (loop $while-in$3 + (if + (i32.eqz + (i32.ge_s + (local.get $i3) + (i32.const 4) + ) + ) + (br $while-out$2) + ) + (block $block7 + (i32.store + (local.get $i1) + (i32.load + (local.get $i2) + ) + ) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 4) + ) + ) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 4) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 4) + ) + ) + ) + (br $while-in$3) + ) + ) + ) + ) + (block $while-out$4 + (loop $while-in$5 + (if + (i32.eqz + (i32.gt_s + (local.get $i3) + (i32.const 0) + ) + ) + (br $while-out$4) + ) + (block $block9 + (i32.store8 + (local.get $i1) + (i32.load8_s + (local.get $i2) + ) + ) + (local.set $i1 + (i32.add + (local.get $i1) + (i32.const 1) + ) + ) + (local.set $i2 + (i32.add + (local.get $i2) + (i32.const 1) + ) + ) + (local.set $i3 + (i32.sub + (local.get $i3) + (i32.const 1) + ) + ) + ) + (br $while-in$5) + ) + ) + (return + (local.get $i4) + ) + ) + ;; CHECK: (func $this-is-effective-i-tell-you (param $0 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $this-is-effective-i-tell-you (type $4) (param $x i32) + (if + (i32.const -1) + (block $block1 + (if + (i32.const 0) + (nop) + ) + (local.set $x + (i32.const 1) + ) + ) + (nop) + ) + (drop + (local.get $x) + ) + ) + ;; CHECK: (func $prefer-remove-copies1 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $prefer-remove-copies1 (type $2) + (local $y i32) + (local $z i32) + (local $x i32) + (local.set $x + (i32.const 0) + ) + (local.set $y + (local.get $x) + ) + (local.set $z + (i32.const 1) + ) + (drop + (local.get $y) + ) + (drop + (local.get $z) + ) + ) + ;; CHECK: (func $prefer-remove-copies2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $prefer-remove-copies2 (type $2) + (local $y i32) + (local $z i32) + (local $x i32) + (local.set $x + (i32.const 0) + ) + (local.set $z + (local.get $x) + ) + (local.set $y + (i32.const 1) + ) + (drop + (local.get $y) + ) + (drop + (local.get $z) + ) + ) + ;; CHECK: (func $in-unreachable + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $x + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $y + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $z + ;; CHECK-NEXT: (br $z) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $z14 + ;; CHECK-NEXT: (br_table $z14 $z14 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $in-unreachable + (local $a i32) + (block $x + (return) + (local.set $a (i32.const 1)) + (drop (local.get $a)) + (local.set $a (local.get $a)) + ) + (block $y + (unreachable) + (local.set $a (i32.const 1)) + (drop (local.get $a)) + (local.set $a (local.get $a)) + ) + (block $z + (br $z) + (local.set $a (i32.const 1)) + (drop (local.get $a)) + (local.set $a (local.get $a)) + ) + (block $z + (br_table $z $z + (i32.const 100) + ) + (local.set $a (i32.const 1)) + (drop (local.get $a)) + (local.set $a (local.get $a)) + ) + ) + ;; CHECK: (func $nop-in-unreachable + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $nop-in-unreachable + (local $x i32) + (block + (unreachable) + (i32.store + (local.get $x) + (local.tee $x (i32.const 0)) + ) + ) + ) + ;; CHECK: (func $loop-backedge + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (loop $while-in7 + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call $set + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (call $get) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 100) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (br $while-in7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $loop-backedge + (local $0 i32) ;; loop phi + (local $1 i32) ;; value for next loop iteration + (local $2 i32) ;; a local that might be merged with with $1, perhaps making us prefer it to removing a backedge copy + (local.set $0 + (i32.const 2) + ) + (block $out + (loop $while-in7 + (local.set $2 (i32.const 0)) ;; 2 interferes with 0 + (call $set (local.get $2)) + (local.set $1 + (i32.add + (local.get $0) + (i32.const 1) + ) + ) + (if (call $get) + (local.set $2 (local.get $1)) ;; copy for 1/2 + ) + (br_if $out (local.get $2)) + (local.set $1 (i32.const 100)) + (local.set $0 (local.get $1)) ;; copy for 1/0, with extra weight should win the tie + (br $while-in7) + ) + ) + ) + ;; CHECK: (func $if-copy1 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $top + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $top) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-copy1 + (local $x i32) + (local $y i32) + (loop $top + (local.set $x + (if (result i32) + (i32.const 1) + (local.get $x) + (local.get $y) + ) + ) + (drop (local.get $x)) + (drop (local.get $y)) + (br $top) + ) + ) + ;; CHECK: (func $if-copy2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $top + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $top) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-copy2 + (local $x i32) + (local $y i32) + (loop $top + (local.set $x + (if (result i32) + (i32.const 1) + (local.get $y) + (local.get $x) + ) + ) + (drop (local.get $x)) + (drop (local.get $y)) + (br $top) + ) + ) + ;; CHECK: (func $if-copy3 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $top + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $top) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-copy3 + (local $x i32) + (local $y i32) + (loop $top + (local.set $x + (if (result i32) + (i32.const 1) + (unreachable) + (local.get $x) + ) + ) + (drop (local.get $x)) + (drop (local.get $y)) + (br $top) + ) + ) + ;; CHECK: (func $if-copy4 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $top + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $top) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-copy4 + (local $x i32) + (local $y i32) + (loop $top + (local.set $x + (if (result i32) + (i32.const 1) + (unreachable) + (local.get $y) + ) + ) + (drop (local.get $x)) + (drop (local.get $y)) + (br $top) + ) + ) + ;; CHECK: (func $if-copy-tee + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (loop $top + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $top) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $if-copy-tee + (local $x i32) + (local $y i32) + (loop $top + (drop + (local.tee $x + (if (result i32) + (i32.const 1) + (local.get $x) + (i32.const 2) + ) + ) + ) + (drop (local.get $x)) + (drop (local.get $y)) + (br $top) + ) + ) + ;; CHECK: (func $tee_br (param $0 i32) (result i32) + ;; CHECK-NEXT: (block $b + ;; CHECK-NEXT: (return + ;; CHECK-NEXT: (br $b) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + (func $tee_br (param $x i32) (result i32) + (block $b + (return + (local.tee $x + (br $b) + ) + ) + ) + (i32.const 1) + ) + ;; CHECK: (func $unused-tee-with-child-if-no-else (param $0 i32) + ;; CHECK-NEXT: (loop $label$0 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (br $label$0) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unused-tee-with-child-if-no-else (param $0 i32) + (loop $label$0 + (drop + (local.tee $0 + (if + (br $label$0) + (nop) + ) + ) + ) + ) + ) + ;; CHECK: (func $tee_if_with_unreachable_else (param $0 f64) (param $1 i32) (result i64) + ;; CHECK-NEXT: (call $tee_if_with_unreachable_else + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (if (result f64) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.lt + ;; CHECK-NEXT: (f64.const -128) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $tee_if_with_unreachable_else (param $0 f64) (param $1 i32) (result i64) + (call $tee_if_with_unreachable_else + (local.tee $0 + (if (result f64) + (local.get $1) + (local.get $0) + (unreachable) + ) + ) + (f64.lt + (f64.const -128) + (local.get $0) + ) + ) + ) + ;; CHECK: (func $tee_if_with_unreachable_true (param $0 f64) (param $1 i32) (result i64) + ;; CHECK-NEXT: (call $tee_if_with_unreachable_else + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (if (result f64) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (f64.lt + ;; CHECK-NEXT: (f64.const -128) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $tee_if_with_unreachable_true (param $0 f64) (param $1 i32) (result i64) + (call $tee_if_with_unreachable_else + (local.tee $0 + (if (result f64) + (local.get $1) + (unreachable) + (local.get $0) + ) + ) + (f64.lt + (f64.const -128) + (local.get $0) + ) + ) + ) + ;; CHECK: (func $pick + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $pick + (local $x i32) + (local $y i32) + (local.set $x (local.get $y)) + (if (i32.const 1) + (local.set $x (i32.const 1)) + ) + (local.set $x (local.get $y)) + (local.set $x (local.get $y)) + ) + ;; CHECK: (func $pick-2 + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $pick-2 + (local $x i32) + (local $y i32) + (local.set $y (local.get $x)) + (if (i32.const 1) + (local.set $y (i32.const 1)) + ) + (local.set $y (local.get $x)) + (local.set $y (local.get $x)) + ) + ;; CHECK: (func $many + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + (func $many + (local $x i32) + (local $y i32) + (local $z i32) + (local $w i32) + (local.set $y (local.get $x)) + (local.set $z (local.get $y)) + (local.set $w (local.get $z)) + (local.set $x (local.get $z)) + (if (i32.const 1) + (local.set $y (i32.const 1)) + ) + (local.set $x (local.get $z)) + (if (i32.const 1) + (local.set $y (i32.const 1)) + ) + (local.set $y (local.get $x)) + (local.set $z (local.get $y)) + (local.set $w (local.get $z)) + (local.set $z (i32.const 2)) + (local.set $x (local.get $z)) + (if (i32.const 1) + (local.set $y (i32.const 1)) + ) + (local.set $y (local.get $x)) + (local.set $z (local.get $y)) + (local.set $w (local.get $z)) + (local.set $z (i32.const 2)) + (local.set $x (local.get $w)) + ) + ;; CHECK: (func $loop-copies (param $0 i32) (param $1 i32) + ;; CHECK-NEXT: (loop $loop + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $loop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $loop-copies (param $x i32) (param $y i32) + (loop $loop + (local.set $x (local.get $y)) + (local.set $y (local.get $x)) + (br_if $loop (local.get $x)) + ) + ) + ;; CHECK: (func $proper-type (result f64) + ;; CHECK-NEXT: (local $0 f64) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (select + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + (func $proper-type (result f64) + (local $var$0 i32) + (local $var$2 f64) + (local.set $var$0 + (select + (i32.const 0) + (i32.const 1) + (local.get $var$0) + ) + ) + (local.tee $var$2 ;; the locals will be reordered, this should be the f64 + (local.get $var$2) + ) + ) + ;; CHECK: (func $reuse-param (param $0 i32) (param $1 i32) (result i32) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (local.tee $0 + ;; CHECK-NEXT: (i32.xor + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.shr_s + ;; CHECK-NEXT: (i32.shl + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 16) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $reuse-param (param $x i32) (param $y i32) (result i32) + (local $temp i32) + (i32.add + (local.tee $temp + (i32.xor + (i32.shr_s + (i32.shl + (local.get $x) ;; $x and $temp do not interfere + (i32.const 16) + ) + (i32.const 16) + ) + (i32.shr_s + (i32.shl + (local.get $y) + (i32.const 16) + ) + (i32.const 16) + ) + ) + ) + (local.get $temp) + ) + ) +) diff --git a/test/lit/passes/code-folding_enable-threads.wast b/test/lit/passes/code-folding_enable-threads.wast new file mode 100644 index 000000000..afbe5ef0e --- /dev/null +++ b/test/lit/passes/code-folding_enable-threads.wast @@ -0,0 +1,433 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; NOTE: This test was ported using port_test.py and could be cleaned up. + +;; RUN: foreach %s %t wasm-opt --code-folding --enable-threads -S -o - | filecheck %s + +(module + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (type $none_=>_f32 (func (result f32))) + + ;; CHECK: (type $13 (func (param f32))) + (type $13 (func (param f32))) + (table 282 282 funcref) + ;; CHECK: (memory $0 1 1) + (memory $0 1 1) + ;; CHECK: (table $0 282 282 funcref) + + ;; CHECK: (func $0 + ;; CHECK-NEXT: (block $label$1 + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $label$3 + ;; CHECK-NEXT: (call_indirect (type $13) + ;; CHECK-NEXT: (block $label$4 + ;; CHECK-NEXT: (br $label$3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 105) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $0 + (block $label$1 + (if + (i32.const 1) + (block $label$3 + (call_indirect (type $13) + (block $label$4 (result f32) ;; but this type may change dangerously + (nop) ;; fold this + (br $label$3) + ) + (i32.const 105) + ) + (nop) ;; with this + ) + ) + ) + ) + ;; CHECK: (func $negative-zero (result f32) + ;; CHECK-NEXT: (if (result f32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (block $label$0 (result f32) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $label$1 (result f32) + ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $negative-zero (result f32) + (if (result f32) + (i32.const 0) + (block $label$0 (result f32) + (f32.const 0) + ) + (block $label$1 (result f32) + (f32.const -0) + ) + ) + ) + ;; CHECK: (func $negative-zero-b (result f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $label$0 (result f32) + ;; CHECK-NEXT: (f32.const -0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $negative-zero-b (result f32) + (if (result f32) + (i32.const 0) + (block $label$0 (result f32) + (f32.const -0) + ) + (block $label$1 (result f32) + (f32.const -0) + ) + ) + ) + ;; CHECK: (func $negative-zero-c (result f32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $label$0 (result f32) + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $negative-zero-c (result f32) + (if (result f32) + (i32.const 0) + (block $label$0 (result f32) + (f32.const 0) + ) + (block $label$1 (result f32) + (f32.const 0) + ) + ) + ) + ;; CHECK: (func $break-target-outside-of-return-merged-code + ;; CHECK-NEXT: (block $label$A + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (block $block0 + ;; CHECK-NEXT: (block $label$B + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (br_table $label$A $label$B + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block2 + ;; CHECK-NEXT: (block $label$C + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (br_table $label$A $label$C + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $break-target-outside-of-return-merged-code + (block $label$A + (if + (unreachable) + (block + (block + (block $label$B + (if + (unreachable) + (br_table $label$A $label$B + (unreachable) + ) + ) + ) + (return) + ) + ) + (block + (block $label$C + (if + (unreachable) + (br_table $label$A $label$C ;; this all looks mergeable, but $label$A is outside + (unreachable) + ) + ) + ) + (return) + ) + ) + ) + ) + ;; CHECK: (func $break-target-inside-all-good + ;; CHECK-NEXT: (block $folding-inner0 + ;; CHECK-NEXT: (block $label$A + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (block $block4 + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $block6 + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $label$B + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (br_table $label$B $label$B + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + (func $break-target-inside-all-good + (block $label$A + (if + (unreachable) + (block + (block + (block $label$B + (if + (unreachable) + (br_table $label$B $label$B + (unreachable) + ) + ) + ) + (return) + ) + ) + (block + (block $label$C + (if + (unreachable) + (br_table $label$C $label$C ;; this all looks mergeable, and is, B ~~ C + (unreachable) + ) + ) + ) + (return) + ) + ) + ) + ) + ;; CHECK: (func $leave-inner-block-type + ;; CHECK-NEXT: (block $label$1 + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (block $label$2 + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $leave-inner-block-type + (block $label$1 + (drop + (block $label$2 (result i32) ;; leave this alone (otherwise, if we make it unreachable, we need to do more updating) + (br_if $label$2 + (unreachable) + (unreachable) + ) + (drop + (i32.const 1) + ) + (br $label$1) + ) + ) + (drop + (i32.const 1) + ) + ) + ) +) +(module + ;; CHECK: (type $none_=>_i32 (func (result i32))) + + ;; CHECK: (memory $0 (shared 1 1)) + (memory $0 (shared 1 1)) + ;; CHECK: (export "func_2224" (func $0)) + (export "func_2224" (func $0)) + ;; CHECK: (func $0 (result i32) + ;; CHECK-NEXT: (local $var$0 i32) + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.load offset=22 + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.atomic.load offset=22 + ;; CHECK-NEXT: (local.get $var$0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $0 (result i32) + (local $var$0 i32) + (if (result i32) + (i32.const 0) + (i32.load offset=22 + (local.get $var$0) + ) + (i32.atomic.load offset=22 + (local.get $var$0) + ) + ) + ) +) +(module + ;; CHECK: (type $0 (func)) + (type $0 (func)) + ;; CHECK: (type $i32_=>_none (func (param i32))) + + ;; CHECK: (global $global$0 (mut i32) (i32.const 10)) + (global $global$0 (mut i32) (i32.const 10)) + ;; CHECK: (func $determinism + ;; CHECK-NEXT: (block $folding-inner0 + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block $label$1 + ;; CHECK-NEXT: (br_if $label$1 + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $label$2 + ;; CHECK-NEXT: (br_if $label$2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: (block $block + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: (block $block1 + ;; CHECK-NEXT: (br $folding-inner0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (global.set $global$0 + ;; CHECK-NEXT: (i32.sub + ;; CHECK-NEXT: (global.get $global$0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + (func $determinism (; 0 ;) (type $0) + (block $label$1 + (br_if $label$1 + (i32.const 1) + ) + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) + ) + (unreachable) + ) + (block $label$2 + (br_if $label$2 + (i32.const 0) + ) + (if + (global.get $global$0) + (block + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) + ) + (unreachable) + ) + ) + (unreachable) + ) + (if + (global.get $global$0) + (block + (global.set $global$0 + (i32.sub + (global.get $global$0) + (i32.const 1) + ) + ) + (unreachable) + ) + ) + (unreachable) + ) + ;; CHECK: (func $careful-of-the-switch (param $0 i32) + ;; CHECK-NEXT: (block $label$1 + ;; CHECK-NEXT: (block $label$3 + ;; CHECK-NEXT: (block $label$5 + ;; CHECK-NEXT: (block $label$7 + ;; CHECK-NEXT: (br_table $label$3 $label$7 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $label$8 + ;; CHECK-NEXT: (br_table $label$3 $label$8 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $label$1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $careful-of-the-switch (param $0 i32) + (block $label$1 + (block $label$3 + (block $label$5 + (block $label$7 ;; this is block is equal to $label$8 when accounting for the internal 7/8 difference + (br_table $label$3 $label$7 ;; the reference to $label$3 must remain valid, cannot hoist out of it! + (i32.const 0) + ) + ) + (br $label$1) + ) + (block $label$8 + (br_table $label$3 $label$8 + (i32.const 0) + ) + ) + (br $label$1) + ) + (unreachable) + ) + ) +) + diff --git a/test/lit/passes/code-pushing_ignore-implicit-traps.wast b/test/lit/passes/code-pushing_ignore-implicit-traps.wast new file mode 100644 index 000000000..a81cf457b --- /dev/null +++ b/test/lit/passes/code-pushing_ignore-implicit-traps.wast @@ -0,0 +1,715 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; NOTE: This test was ported using port_test.py and could be cleaned up. + +;; RUN: foreach %s %t wasm-opt --code-pushing --ignore-implicit-traps -S -o - | filecheck %s + +(module + (memory 1) + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (type $none_=>_i32 (func (result i32))) + + ;; CHECK: (memory $0 1) + + ;; CHECK: (func $push1 + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push1 + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $push2 + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push2 + (local $x i32) + (local $y i32) + (block $out + (local.set $x (i32.const 1)) + (local.set $y (i32.const 3)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + (drop (local.get $y)) + ) + ) + ;; CHECK: (func $push1-twice + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push1-twice + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (i32.const 2)) + (br_if $out (i32.const 3)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $push1-twiceb + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push1-twiceb + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (i32.const 2)) + (nop) + (br_if $out (i32.const 3)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $push2-twice + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push2-twice + (local $x i32) + (local $y i32) + (block $out + (local.set $x (i32.const 1)) + (local.set $y (i32.const 3)) + (br_if $out (i32.const 2)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + (drop (local.get $y)) + ) + ) + ;; CHECK: (func $ignore-last + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ignore-last + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (i32.const 2)) + ) + ) + ;; CHECK: (func $ignore-last2 + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $ignore-last2 + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (nop) + (nop) + (br_if $out (i32.const 2)) + ) + ) + ;; CHECK: (func $push-if + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push-if + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (if (i32.const 2) (nop)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $push-dropped (result i32) + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out (result i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push-dropped (result i32) + (local $x i32) + (block $out (result i32) + (local.set $x (i32.const 1)) + (drop (br_if $out (i32.const 2) (i32.const 3))) + (drop (local.get $x)) + (i32.const 4) + ) + ) + ;; CHECK: (func $push-past-stuff + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (call $push-past-stuff) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $push-past-stuff + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (call $push-past-stuff) + (drop (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $fail-then-push + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $fail-then-push + (local $x i32) + (local $y i32) + (block $out + (local.set $x (i32.const 1)) + (drop (local.get $x)) + (br_if $out (i32.const 2)) + (local.set $y (i32.const 1)) + (br_if $out (i32.const 3)) + (drop (local.get $x)) + (drop (local.get $y)) + ) + ) + ;; and now for stuff that should *not* be pushed + ;; CHECK: (func $used + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $used + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (local.get $x)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $not-sfa + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $not-sfa + (local $x i32) + (local.set $x (i32.const 1)) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $not-sfa2 + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $not-sfa2 + (local $x i32) + (drop (local.get $x)) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $used-out + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $used-out + (local $x i32) + (block $out + (local.set $x (i32.const 1)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + (drop (local.get $x)) + ) + ;; CHECK: (func $value-might-interfere + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $value-might-interfere ;; but doesn't + (local $x i32) + (block $out + (local.set $x (i32.load (i32.const 0))) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $value-interferes + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $value-interferes + (local $x i32) + (block $out + (local.set $x (i32.load (i32.const 0))) + (i32.store (i32.const 1) (i32.const 3)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $value-interferes-accumulation + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (i32.store + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $value-interferes-accumulation + (local $x i32) + (block $out + (local.set $x (i32.load (i32.const 0))) + (nop) + (i32.store (i32.const 1) (i32.const 3)) + (nop) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $value-interferes-in-pushpoint + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.load + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (call $value-interferes) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $value-interferes-in-pushpoint + (local $x i32) + (block $out + (local.set $x (i32.load (i32.const 0))) + (if (i32.const 1) + (call $value-interferes) + ) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $values-might-interfere + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (call $push-dropped) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (call $push-dropped) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $values-might-interfere ;; they don't, as we keep the order - but here their side effects prevent pushing + (local $x i32) + (local $y i32) + (block $out + (local.set $x (call $push-dropped)) + (local.set $y (call $push-dropped)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + (drop (local.get $y)) + ) + ) + ;; CHECK: (func $unpushed-interferes + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (call $push-dropped) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (call $push-dropped) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unpushed-interferes + (local $x i32) + (local $y i32) + (block $out + (local.set $x (call $push-dropped)) + (local.set $y (call $push-dropped)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + (drop (local.get $y)) + ) + (drop (local.get $y)) ;; $y can't be pushed, so x can't be + ) + ;; CHECK: (func $unpushed-ignorable + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unpushed-ignorable + (local $x i32) + (local $y i32) + (block $out + (local.set $x (i32.const 1)) + (local.set $y (i32.const 3)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + (drop (local.get $y)) + ) + (drop (local.get $x)) ;; $x can't be pushed, but y doesn't care + ) + ;; CHECK: (func $unpushed-ignorable-side-effect + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (local $y i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (call $push-dropped) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $y + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $y) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unpushed-ignorable-side-effect + (local $x i32) + (local $y i32) + (block $out + (local.set $x (call $push-dropped)) ;; $x can't be pushed, but y doesn't care + (local.set $y (i32.const 3)) + (br_if $out (i32.const 2)) + (drop (local.get $x)) + (drop (local.get $y)) + ) + ) + ;; CHECK: (func $unpushed-side-effect-into-drop + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (call $push-dropped) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unpushed-side-effect-into-drop + (local $x i32) + (block $out + (local.set $x (call $push-dropped)) + (br_if $out (i32.const 1)) + (drop (local.get $x)) + ) + ) + ;; CHECK: (func $unpushed-side-effect-into-if + ;; CHECK-NEXT: (local $x i32) + ;; CHECK-NEXT: (block $out + ;; CHECK-NEXT: (local.set $x + ;; CHECK-NEXT: (call $push-dropped) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br_if $out + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unpushed-side-effect-into-if + (local $x i32) + (block $out + (local.set $x (call $push-dropped)) + (br_if $out (i32.const 1)) + (if + (local.get $x) + (nop) + ) + ) + ) +) + diff --git a/test/lit/passes/const-hoisting.wast b/test/lit/passes/const-hoisting.wast new file mode 100644 index 000000000..276cb8045 --- /dev/null +++ b/test/lit/passes/const-hoisting.wast @@ -0,0 +1,834 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; NOTE: This test was ported using port_test.py and could be cleaned up. + +;; RUN: foreach %s %t wasm-opt --const-hoisting -S -o - | filecheck %s + +(module + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (func $10-of-each + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (local $1 i32) + ;; CHECK-NEXT: (local $2 i32) + ;; CHECK-NEXT: (local $3 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (i32.const 1048575) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $2 + ;; CHECK-NEXT: (i32.const 1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $3 + ;; CHECK-NEXT: (i32.const -8193) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (i32.const -1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (i32.const -1048577) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 63) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8191) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -64) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -65) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const -8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $3) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $10-of-each + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + (drop (i32.const 0)) ;; 1 byte + (drop (i32.const 63)) ;; 1 byte + (drop (i32.const 64)) ;; 2 bytes + (drop (i32.const 8191)) ;; 2 bytes + (drop (i32.const 8192)) ;; 3 bytes + (drop (i32.const 1048575)) ;; 3 bytes + (drop (i32.const 1048576)) ;; 4 bytes + (drop (i32.const -64)) ;; 1 byte + (drop (i32.const -65)) ;; 2 bytes + (drop (i32.const -8192)) ;; 2 bytes + (drop (i32.const -8193)) ;; 3 bytes + (drop (i32.const -1048576)) ;; 3 bytes + (drop (i32.const -1048577)) ;; 4 bytes + ) + ;; CHECK: (func $floats-10-times + ;; CHECK-NEXT: (local $0 f32) + ;; CHECK-NEXT: (local $1 f64) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $1 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $floats-10-times + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + (drop (f32.const 0)) ;; 4 bytes + (drop (f64.const 0)) ;; 8 bytes + ) + ;; CHECK: (func $too-few + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $too-few + (drop (i32.const 8192)) ;; 3 bytes, need 6 appearances + (drop (i32.const 8192)) + (drop (i32.const 8192)) + (drop (i32.const 8192)) + (drop (i32.const 8192)) + ) + ;; CHECK: (func $just-enough + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 8192) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $just-enough + (drop (i32.const 8192)) ;; 3 bytes, need 6 appearances + (drop (i32.const 8192)) + (drop (i32.const 8192)) + (drop (i32.const 8192)) + (drop (i32.const 8192)) + (drop (i32.const 8192)) + ) + ;; CHECK: (func $too-few-b + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $too-few-b + (drop (i32.const 1048576)) ;; 4 bytes, need 4 appearances + (drop (i32.const 1048576)) + (drop (i32.const 1048576)) + ) + ;; CHECK: (func $enough-b + ;; CHECK-NEXT: (local $0 i32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (i32.const 1048576) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $enough-b + (drop (i32.const 1048576)) ;; 4 bytes, need 4 appearances + (drop (i32.const 1048576)) + (drop (i32.const 1048576)) + (drop (i32.const 1048576)) + ) + ;; CHECK: (func $too-few-c + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $too-few-c + (drop (f32.const 0)) ;; 4 bytes, need 4 appearances + (drop (f32.const 0)) + (drop (f32.const 0)) + ) + ;; CHECK: (func $enough-c + ;; CHECK-NEXT: (local $0 f32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $enough-c + (drop (f32.const 0)) ;; 4 bytes, need 4 appearances + (drop (f32.const 0)) + (drop (f32.const 0)) + (drop (f32.const 0)) + ) + ;; CHECK: (func $too-few-d + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $too-few-d + (drop (f64.const 0)) ;; 8 bytes, need 2 appearances + ) + ;; CHECK: (func $enough-d + ;; CHECK-NEXT: (local $0 f64) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $0 + ;; CHECK-NEXT: (f64.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $enough-d + (drop (f64.const 0)) ;; 4 bytes, need 4 appearances + (drop (f64.const 0)) + ) +) + |