summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-05-16 20:44:02 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-05-17 11:04:00 -0700
commit5d76c53d350cc4565c8c4f4298c8fd346ca8fcb5 (patch)
treee539c33bfff5d3d677a1731e4185887edb0fba63 /test
parent700846f46148cc92485c59b37b46272978ab3e42 (diff)
downloadbinaryen-5d76c53d350cc4565c8c4f4298c8fd346ca8fcb5.tar.gz
binaryen-5d76c53d350cc4565c8c4f4298c8fd346ca8fcb5.tar.bz2
binaryen-5d76c53d350cc4565c8c4f4298c8fd346ca8fcb5.zip
add a learning local coalescer
Diffstat (limited to 'test')
-rw-r--r--test/passes/coalesce-locals-learning.txt680
-rw-r--r--test/passes/coalesce-locals-learning.wast594
2 files changed, 1274 insertions, 0 deletions
diff --git a/test/passes/coalesce-locals-learning.txt b/test/passes/coalesce-locals-learning.txt
new file mode 100644
index 000000000..03e58347a
--- /dev/null
+++ b/test/passes/coalesce-locals-learning.txt
@@ -0,0 +1,680 @@
+(module
+ (memory 10)
+ (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
+ (type $FUNCSIG$iii (func (param i32 i32) (result i32)))
+ (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32))
+ (func $nothing-to-do
+ (local $0 i32)
+ (nop)
+ )
+ (func $merge
+ (local $0 i32)
+ (nop)
+ )
+ (func $leave-type
+ (local $0 i32)
+ (local $1 f32)
+ (nop)
+ )
+ (func $leave-interfere
+ (local $0 i32)
+ (local $1 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (set_local $1
+ (i32.const 0)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $almost-interfere
+ (local $0 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $0)
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $0)
+ )
+ (func $redundant-copy
+ (local $0 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $0)
+ (get_local $0)
+ )
+ (func $ineffective-store
+ (local $0 i32)
+ (i32.const 0)
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $0)
+ )
+ (func $block
+ (local $0 i32)
+ (block $block0
+ (set_local $0
+ (i32.const 0)
+ )
+ )
+ (get_local $0)
+ )
+ (func $see-both-sides
+ (local $0 i32)
+ (local $1 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (block $block0
+ (set_local $1
+ (i32.const 0)
+ )
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $see-br-and-ignore-dead
+ (local $0 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (block $block
+ (br $block)
+ (i32.const 0)
+ (get_local $0)
+ (i32.const -1)
+ )
+ (get_local $0)
+ )
+ (func $see-block-body
+ (local $0 i32)
+ (local $1 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (block $block
+ (set_local $1
+ (i32.const 0)
+ )
+ (get_local $1)
+ (br $block)
+ )
+ (get_local $0)
+ )
+ (func $zero-init
+ (local $0 i32)
+ (local $1 i32)
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $multi
+ (local $0 i32)
+ (local $1 i32)
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $if-else
+ (local $0 i32)
+ (local $1 i32)
+ (if
+ (i32.const 0)
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ (func $if-else-parallel
+ (local $0 i32)
+ (if
+ (i32.const 0)
+ (block $block1
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $0)
+ )
+ (block $block3
+ (set_local $0
+ (i32.const 1)
+ )
+ (get_local $0)
+ )
+ )
+ )
+ (func $if-else-after
+ (local $0 i32)
+ (local $1 i32)
+ (if
+ (i32.const 0)
+ (set_local $0
+ (i32.const 0)
+ )
+ (set_local $1
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $if-else-through
+ (local $0 i32)
+ (local $1 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (set_local $1
+ (i32.const 1)
+ )
+ (if
+ (i32.const 0)
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $if-through
+ (local $0 i32)
+ (local $1 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (set_local $1
+ (i32.const 1)
+ )
+ (if
+ (i32.const 0)
+ (i32.const 1)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $if-through2
+ (local $0 i32)
+ (local $1 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (if
+ (i32.const 0)
+ (set_local $1
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (func $if-through2
+ (local $0 i32)
+ (local $1 i32)
+ (set_local $0
+ (i32.const 0)
+ )
+ (if
+ (i32.const 0)
+ (block $block1
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ )
+ (func $if2
+ (local $0 i32)
+ (local $1 i32)
+ (if
+ (set_local $0
+ (i32.const 0)
+ )
+ (block $block1
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ )
+ (func $if3
+ (local $0 i32)
+ (local $1 i32)
+ (if
+ (i32.const 0)
+ (block $block1
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $0)
+ )
+ )
+ (get_local $1)
+ )
+ (func $if4
+ (local $0 i32)
+ (if
+ (i32.const 0)
+ (block $block1
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $0)
+ (set_local $0
+ (i32.const 1)
+ )
+ )
+ )
+ (get_local $0)
+ )
+ (func $if5
+ (local $0 i32)
+ (local $1 i32)
+ (if
+ (i32.const 0)
+ (block $block1
+ (get_local $0)
+ (set_local $1
+ (i32.const 1)
+ )
+ )
+ )
+ (get_local $1)
+ )
+ (func $loop
+ (local $0 i32)
+ (local $1 i32)
+ (loop $out $in
+ (get_local $0)
+ (set_local $0
+ (i32.const 0)
+ )
+ (get_local $1)
+ (br $in)
+ )
+ )
+ (func $interfere-in-dead
+ (local $0 i32)
+ (block $block
+ (br $block)
+ (get_local $0)
+ (get_local $0)
+ )
+ )
+ (func $interfere-in-dead2
+ (local $0 i32)
+ (block $block
+ (unreachable)
+ (get_local $0)
+ (get_local $0)
+ )
+ )
+ (func $interfere-in-dead3
+ (local $0 i32)
+ (block $block
+ (return)
+ (get_local $0)
+ (get_local $0)
+ )
+ )
+ (func $params (param $0 i32) (param $1 f32)
+ (local $2 i32)
+ (local $3 i32)
+ (get_local $0)
+ (get_local $2)
+ (get_local $3)
+ )
+ (func $interfere-in-dead
+ (local $0 i32)
+ (local $1 i32)
+ (block $block
+ (br_if $block
+ (i32.const 0)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ (func $switch
+ (local $0 i32)
+ (local $1 i32)
+ (local $2 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)
+ )
+ (get_local $0)
+ )
+ (get_local $0)
+ )
+ (get_local $1)
+ )
+ (get_local $2)
+ )
+ (func $greedy-can-be-happy
+ (local $0 i32)
+ (local $1 i32)
+ (if
+ (i32.const 0)
+ (if
+ (i32.const 1)
+ (if
+ (i32.const 2)
+ (block $block3
+ (set_local $0
+ (i32.const 100)
+ )
+ (set_local $1
+ (i32.const 101)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (block $block5
+ (set_local $0
+ (i32.const 102)
+ )
+ (set_local $1
+ (i32.const 103)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ (if
+ (i32.const 3)
+ (block $block8
+ (set_local $0
+ (i32.const 104)
+ )
+ (set_local $1
+ (i32.const 105)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (block $block10
+ (set_local $0
+ (i32.const 106)
+ )
+ (set_local $1
+ (i32.const 107)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ )
+ (if
+ (i32.const 4)
+ (block $block13
+ (set_local $0
+ (i32.const 108)
+ )
+ (set_local $1
+ (i32.const 109)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ (block $block15
+ (set_local $0
+ (i32.const 110)
+ )
+ (set_local $1
+ (i32.const 111)
+ )
+ (get_local $0)
+ (get_local $1)
+ )
+ )
+ )
+ )
+ (func $greedy-can-be-sad
+ (local $0 i32)
+ (local $1 i32)
+ (if
+ (i32.const 0)
+ (if
+ (i32.const 1)
+ (if
+ (i32.const 2)
+ (block $block3
+ (set_local $1
+ (i32.const 100)
+ )
+ (set_local $0
+ (i32.const 101)
+ )
+ (get_local $1)
+ (get_local $0)
+ )
+ (block $block5
+ (set_local $1
+ (i32.const 102)
+ )
+ (set_local $0
+ (i32.const 103)
+ )
+ (get_local $1)
+ (get_local $0)
+ )
+ )
+ (if
+ (i32.const 3)
+ (block $block8
+ (set_local $1
+ (i32.const 104)
+ )
+ (set_local $0
+ (i32.const 105)
+ )
+ (get_local $1)
+ (get_local $0)
+ )
+ (block $block10
+ (set_local $1
+ (i32.const 106)
+ )
+ (set_local $0
+ (i32.const 107)
+ )
+ (get_local $1)
+ (get_local $0)
+ )
+ )
+ )
+ (if
+ (i32.const 4)
+ (block $block13
+ (set_local $1
+ (i32.const 108)
+ )
+ (set_local $0
+ (i32.const 109)
+ )
+ (get_local $1)
+ (get_local $0)
+ )
+ (block $block15
+ (set_local $1
+ (i32.const 110)
+ )
+ (set_local $0
+ (i32.const 111)
+ )
+ (get_local $1)
+ (get_local $0)
+ )
+ )
+ )
+ )
+ (func $_memcpy (param $0 i32) (param $1 i32) (param $2 i32) (result i32)
+ (local $3 i32)
+ (if
+ (i32.ge_s
+ (get_local $2)
+ (i32.const 4096)
+ )
+ (get_local $0)
+ )
+ (set_local $3
+ (get_local $0)
+ )
+ (if
+ (i32.eq
+ (i32.and
+ (get_local $0)
+ (i32.const 3)
+ )
+ (i32.and
+ (get_local $1)
+ (i32.const 3)
+ )
+ )
+ (block $block2
+ (loop $while-out$0 $while-in$1
+ (if
+ (i32.eqz
+ (i32.and
+ (get_local $0)
+ (i32.const 3)
+ )
+ )
+ (br $while-out$0)
+ )
+ (block $block4
+ (if
+ (i32.eqz
+ (get_local $2)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (i32.store8
+ (get_local $0)
+ (i32.load8_s
+ (get_local $1)
+ )
+ )
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
+ )
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
+ )
+ )
+ (br $while-in$1)
+ )
+ (loop $while-out$2 $while-in$3
+ (if
+ (i32.eqz
+ (i32.ge_s
+ (get_local $2)
+ (i32.const 4)
+ )
+ )
+ (br $while-out$2)
+ )
+ (block $block7
+ (i32.store
+ (get_local $0)
+ (i32.load
+ (get_local $1)
+ )
+ )
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 4)
+ )
+ )
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 4)
+ )
+ )
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 4)
+ )
+ )
+ )
+ (br $while-in$3)
+ )
+ )
+ )
+ (loop $while-out$4 $while-in$5
+ (if
+ (i32.eqz
+ (i32.gt_s
+ (get_local $2)
+ (i32.const 0)
+ )
+ )
+ (br $while-out$4)
+ )
+ (block $block9
+ (i32.store8
+ (get_local $0)
+ (i32.load8_s
+ (get_local $1)
+ )
+ )
+ (set_local $0
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (set_local $1
+ (i32.add
+ (get_local $1)
+ (i32.const 1)
+ )
+ )
+ (set_local $2
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
+ )
+ )
+ (br $while-in$5)
+ )
+ (return
+ (get_local $3)
+ )
+ )
+ (func $this-is-effective-i-tell-you (param $0 i32)
+ (if
+ (i32.const -1)
+ (block $block1
+ (if
+ (i32.const 0)
+ (nop)
+ )
+ (set_local $0
+ (i32.const 1)
+ )
+ )
+ (nop)
+ )
+ (get_local $0)
+ )
+)
diff --git a/test/passes/coalesce-locals-learning.wast b/test/passes/coalesce-locals-learning.wast
new file mode 100644
index 000000000..a7152d16a
--- /dev/null
+++ b/test/passes/coalesce-locals-learning.wast
@@ -0,0 +1,594 @@
+(module
+ (memory 10)
+ (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32)))
+ (import $_emscripten_autodebug_i32 "env" "_emscripten_autodebug_i32" (param i32 i32) (result i32))
+ (table)
+ (func $nothing-to-do
+ (local $x i32)
+ )
+ (func $merge
+ (local $x i32)
+ (local $y i32)
+ )
+ (func $leave-type
+ (local $x i32)
+ (local $y f32)
+ )
+ (func $leave-interfere
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (set_local $y (i32.const 0))
+ (get_local $x)
+ (get_local $y)
+ )
+ (func $almost-interfere
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (get_local $x)
+ (set_local $y (i32.const 0))
+ (get_local $y)
+ )
+ (func $redundant-copy
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (set_local $y (get_local $x))
+ (get_local $y)
+ )
+ (func $ineffective-store
+ (local $x i32)
+ (set_local $x (i32.const 0))
+ (set_local $x (i32.const 0))
+ (get_local $x)
+ )
+ (func $block
+ (local $x i32)
+ (block
+ (set_local $x (i32.const 0))
+ )
+ (get_local $x)
+ )
+ (func $see-both-sides
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (block
+ (set_local $y (i32.const 0))
+ )
+ (get_local $x)
+ (get_local $y)
+ )
+ (func $see-br-and-ignore-dead
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (block $block
+ (br $block)
+ (set_local $y (i32.const 0))
+ (get_local $y)
+ (set_local $x (i32.const -1))
+ )
+ (get_local $x)
+ )
+ (func $see-block-body
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (block $block
+ (set_local $y (i32.const 0))
+ (get_local $y)
+ (br $block)
+ )
+ (get_local $x)
+ )
+ (func $zero-init
+ (local $x i32)
+ (local $y i32)
+ (get_local $x)
+ (get_local $y)
+ )
+ (func $multi
+ (local $x i32) ;; x is free, but y and z conflict
+ (local $y i32)
+ (local $z i32)
+ (get_local $y)
+ (get_local $z)
+ )
+ (func $if-else
+ (local $x i32)
+ (local $y i32)
+ (if ;; x and y conflict when they are merged into their shared predecessor
+ (i32.const 0)
+ (get_local $x)
+ (get_local $y)
+ )
+ )
+ (func $if-else-parallel
+ (local $x i32)
+ (local $y i32)
+ (if
+ (i32.const 0)
+ (block
+ (set_local $x (i32.const 0))
+ (get_local $x)
+ )
+ (block
+ (set_local $y (i32.const 1))
+ (get_local $y)
+ )
+ )
+ )
+ (func $if-else-after
+ (local $x i32)
+ (local $y i32)
+ (if
+ (i32.const 0)
+ (set_local $x (i32.const 0))
+ (set_local $y (i32.const 1))
+ )
+ (get_local $x)
+ (get_local $y)
+ )
+ (func $if-else-through
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (set_local $y (i32.const 1))
+ (if
+ (i32.const 0)
+ (i32.const 1)
+ (i32.const 2)
+ )
+ (get_local $x)
+ (get_local $y)
+ )
+ (func $if-through
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (set_local $y (i32.const 1))
+ (if
+ (i32.const 0)
+ (i32.const 1)
+ )
+ (get_local $x)
+ (get_local $y)
+ )
+ (func $if-through2
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (if
+ (i32.const 0)
+ (set_local $y (i32.const 1))
+ )
+ (get_local $x)
+ (get_local $y)
+ )
+ (func $if-through2
+ (local $x i32)
+ (local $y i32)
+ (set_local $x (i32.const 0))
+ (if
+ (i32.const 0)
+ (block
+ (get_local $x)
+ (get_local $y)
+ )
+ )
+ )
+ (func $if2
+ (local $x i32)
+ (local $y i32)
+ (if
+ (set_local $x (i32.const 0))
+ (block
+ (get_local $x)
+ (get_local $y)
+ )
+ )
+ )
+ (func $if3
+ (local $x i32)
+ (local $y i32)
+ (if
+ (i32.const 0)
+ (block
+ (set_local $x (i32.const 0))
+ (get_local $x)
+ )
+ )
+ (get_local $y)
+ )
+ (func $if4
+ (local $x i32)
+ (local $y i32)
+ (if
+ (i32.const 0)
+ (block
+ (set_local $x (i32.const 0))
+ (get_local $x)
+ (set_local $y (i32.const 1)) ;; we might not go through here, but it's ok
+ )
+ )
+ (get_local $y)
+ )
+ (func $if5
+ (local $x i32)
+ (local $y i32)
+ (if
+ (i32.const 0)
+ (block
+ (get_local $x) ;; we might go through here, and it causes interference
+ (set_local $y (i32.const 1))
+ )
+ )
+ (get_local $y)
+ )
+ (func $loop
+ (local $x i32)
+ (local $y i32)
+ (loop $out $in
+ (get_local $x)
+ (set_local $x (i32.const 0)) ;; effective, due to looping
+ (get_local $y)
+ (br $in)
+ )
+ )
+ (func $interfere-in-dead
+ (local $x i32)
+ (local $y i32)
+ (block $block
+ (br $block)
+ (get_local $x)
+ (get_local $y)
+ )
+ )
+ (func $interfere-in-dead2
+ (local $x i32)
+ (local $y i32)
+ (block $block
+ (unreachable)
+ (get_local $x)
+ (get_local $y)
+ )
+ )
+ (func $interfere-in-dead3
+ (local $x i32)
+ (local $y i32)
+ (block $block
+ (return)
+ (get_local $x)
+ (get_local $y)
+ )
+ )
+ (func $params (param $p i32) (param $q f32)
+ (local $x i32) ;; x is free, but others conflict
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (get_local $y)
+ (get_local $z)
+ (get_local $w)
+ )
+ (func $interfere-in-dead
+ (local $x i32)
+ (local $y i32)
+ (block $block
+ (br_if $block (i32.const 0))
+ (get_local $x)
+ (get_local $y)
+ )
+ )
+ (func $switch
+ (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)
+ )
+ (get_local $x) ;; unreachable
+ )
+ (get_local $y)
+ )
+ (get_local $z)
+ )
+ (get_local $w)
+ )
+ (func $greedy-can-be-happy
+ (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
+ (set_local $x1 (i32.const 100))
+ (set_local $y2 (i32.const 101))
+ (get_local $x1)
+ (get_local $y2)
+ )
+ (block
+ (set_local $x1 (i32.const 102))
+ (set_local $y3 (i32.const 103))
+ (get_local $x1)
+ (get_local $y3)
+ )
+ )
+ (if
+ (i32.const 3)
+ (block
+ (set_local $x2 (i32.const 104))
+ (set_local $y1 (i32.const 105))
+ (get_local $x2)
+ (get_local $y1)
+ )
+ (block
+ (set_local $x2 (i32.const 106))
+ (set_local $y3 (i32.const 107))
+ (get_local $x2)
+ (get_local $y3)
+ )
+ )
+ )
+ (if
+ (i32.const 4)
+ (block
+ (set_local $x3 (i32.const 108))
+ (set_local $y1 (i32.const 109))
+ (get_local $x3)
+ (get_local $y1)
+ )
+ (block
+ (set_local $x3 (i32.const 110))
+ (set_local $y2 (i32.const 111))
+ (get_local $x3)
+ (get_local $y2)
+ )
+ )
+ )
+ )
+ (func $greedy-can-be-sad
+ (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
+ (set_local $x1 (i32.const 100))
+ (set_local $y2 (i32.const 101))
+ (get_local $x1)
+ (get_local $y2)
+ )
+ (block
+ (set_local $x1 (i32.const 102))
+ (set_local $y3 (i32.const 103))
+ (get_local $x1)
+ (get_local $y3)
+ )
+ )
+ (if
+ (i32.const 3)
+ (block
+ (set_local $x2 (i32.const 104))
+ (set_local $y1 (i32.const 105))
+ (get_local $x2)
+ (get_local $y1)
+ )
+ (block
+ (set_local $x2 (i32.const 106))
+ (set_local $y3 (i32.const 107))
+ (get_local $x2)
+ (get_local $y3)
+ )
+ )
+ )
+ (if
+ (i32.const 4)
+ (block
+ (set_local $x3 (i32.const 108))
+ (set_local $y1 (i32.const 109))
+ (get_local $x3)
+ (get_local $y1)
+ )
+ (block
+ (set_local $x3 (i32.const 110))
+ (set_local $y2 (i32.const 111))
+ (get_local $x3)
+ (get_local $y2)
+ )
+ )
+ )
+ )
+ (func $_memcpy (param $i1 i32) (param $i2 i32) (param $i3 i32) (result i32)
+ (local $i4 i32)
+ (if
+ (i32.ge_s
+ (get_local $i3)
+ (i32.const 4096)
+ )
+ (get_local $i1)
+ (get_local $i2)
+ (get_local $i3)
+ (return)
+ )
+ (set_local $i4
+ (get_local $i1)
+ )
+ (if
+ (i32.eq
+ (i32.and
+ (get_local $i1)
+ (i32.const 3)
+ )
+ (i32.and
+ (get_local $i2)
+ (i32.const 3)
+ )
+ )
+ (block
+ (loop $while-out$0 $while-in$1
+ (if
+ (i32.eqz
+ (i32.and
+ (get_local $i1)
+ (i32.const 3)
+ )
+ )
+ (br $while-out$0)
+ )
+ (block
+ (if
+ (i32.eqz
+ (get_local $i3)
+ )
+ (return
+ (get_local $i4)
+ )
+ )
+ (i32.store8
+ (get_local $i1)
+ (i32.load8_s
+ (get_local $i2)
+ )
+ )
+ (set_local $i1
+ (i32.add
+ (get_local $i1)
+ (i32.const 1)
+ )
+ )
+ (set_local $i2
+ (i32.add
+ (get_local $i2)
+ (i32.const 1)
+ )
+ )
+ (set_local $i3
+ (i32.sub
+ (get_local $i3)
+ (i32.const 1)
+ )
+ )
+ )
+ (br $while-in$1)
+ )
+ (loop $while-out$2 $while-in$3
+ (if
+ (i32.eqz
+ (i32.ge_s
+ (get_local $i3)
+ (i32.const 4)
+ )
+ )
+ (br $while-out$2)
+ )
+ (block
+ (i32.store
+ (get_local $i1)
+ (i32.load
+ (get_local $i2)
+ )
+ )
+ (set_local $i1
+ (i32.add
+ (get_local $i1)
+ (i32.const 4)
+ )
+ )
+ (set_local $i2
+ (i32.add
+ (get_local $i2)
+ (i32.const 4)
+ )
+ )
+ (set_local $i3
+ (i32.sub
+ (get_local $i3)
+ (i32.const 4)
+ )
+ )
+ )
+ (br $while-in$3)
+ )
+ )
+ )
+ (loop $while-out$4 $while-in$5
+ (if
+ (i32.eqz
+ (i32.gt_s
+ (get_local $i3)
+ (i32.const 0)
+ )
+ )
+ (br $while-out$4)
+ )
+ (block
+ (i32.store8
+ (get_local $i1)
+ (i32.load8_s
+ (get_local $i2)
+ )
+ )
+ (set_local $i1
+ (i32.add
+ (get_local $i1)
+ (i32.const 1)
+ )
+ )
+ (set_local $i2
+ (i32.add
+ (get_local $i2)
+ (i32.const 1)
+ )
+ )
+ (set_local $i3
+ (i32.sub
+ (get_local $i3)
+ (i32.const 1)
+ )
+ )
+ )
+ (br $while-in$5)
+ )
+ (return
+ (get_local $i4)
+ )
+ )
+ (func $this-is-effective-i-tell-you (param $x i32)
+ (if
+ (i32.const -1)
+ (block
+ (if ;; this is important for the bug
+ (i32.const 0)
+ (nop)
+ )
+ (set_local $x ;; this set is effective!
+ (i32.const 1)
+ )
+ )
+ (nop) ;; this is enough for the bug
+ )
+ (get_local $x) ;; this ends up with the wrong value in the test
+ )
+)
+