summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/help/wasm-opt.test3
-rw-r--r--test/lit/help/wasm2js.test3
-rw-r--r--test/passes/spill-pointers.txt1293
-rw-r--r--test/passes/spill-pointers.wast338
4 files changed, 1637 insertions, 0 deletions
diff --git a/test/lit/help/wasm-opt.test b/test/lit/help/wasm-opt.test
index 1985d70ec..bb111d92e 100644
--- a/test/lit/help/wasm-opt.test
+++ b/test/lit/help/wasm-opt.test
@@ -384,6 +384,9 @@
;; CHECK-NEXT: --souperify-single-use emit Souper IR in text form
;; CHECK-NEXT: (single-use nodes only)
;; CHECK-NEXT:
+;; CHECK-NEXT: --spill-pointers spill pointers to the C stack
+;; CHECK-NEXT: (useful for Boehm-style GC)
+;; CHECK-NEXT:
;; CHECK-NEXT: --ssa ssa-ify variables so that they
;; CHECK-NEXT: have a single assignment
;; CHECK-NEXT:
diff --git a/test/lit/help/wasm2js.test b/test/lit/help/wasm2js.test
index 5c0f249e3..917b8750a 100644
--- a/test/lit/help/wasm2js.test
+++ b/test/lit/help/wasm2js.test
@@ -346,6 +346,9 @@
;; CHECK-NEXT: --souperify-single-use emit Souper IR in text form
;; CHECK-NEXT: (single-use nodes only)
;; CHECK-NEXT:
+;; CHECK-NEXT: --spill-pointers spill pointers to the C stack
+;; CHECK-NEXT: (useful for Boehm-style GC)
+;; CHECK-NEXT:
;; CHECK-NEXT: --ssa ssa-ify variables so that they
;; CHECK-NEXT: have a single assignment
;; CHECK-NEXT:
diff --git a/test/passes/spill-pointers.txt b/test/passes/spill-pointers.txt
new file mode 100644
index 000000000..dcd8b2cbf
--- /dev/null
+++ b/test/passes/spill-pointers.txt
@@ -0,0 +1,1293 @@
+(module
+ (type $none_=>_none (func))
+ (type $i32_=>_i32 (func (param i32) (result i32)))
+ (type $none_=>_i32 (func (result i32)))
+ (type $ii (func (param i32 i32)))
+ (type $i32_=>_none (func (param i32)))
+ (type $f64_=>_none (func (param f64)))
+ (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32))
+ (import "env" "segfault" (func $segfault (param i32)))
+ (global $stack_ptr (mut i32) (global.get $STACKTOP$asm2wasm$import))
+ (memory $0 10)
+ (table $0 1 1 funcref)
+ (elem (i32.const 0))
+ (func $nothing
+ (nop)
+ )
+ (func $not-alive
+ (local $x i32)
+ (local.set $x
+ (i32.const 1)
+ )
+ (call $nothing)
+ )
+ (func $spill
+ (local $x i32)
+ (local $1 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ )
+ (func $ignore-non-pointers
+ (local $x i32)
+ (local $y i64)
+ (local $z f32)
+ (local $w f64)
+ (local $4 i32)
+ (local.set $4
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $4)
+ (i32.const 16)
+ )
+ )
+ (block
+ (local.set $x
+ (i32.const 1)
+ )
+ (local.set $y
+ (i64.const 1)
+ )
+ (local.set $z
+ (f32.const 1)
+ )
+ (local.set $w
+ (f64.const 1)
+ )
+ (block
+ (i32.store
+ (local.get $4)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (local.get $y)
+ )
+ (drop
+ (local.get $z)
+ )
+ (drop
+ (local.get $w)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $4)
+ )
+ )
+ (func $spill4
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local $4 i32)
+ (local.set $4
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $4)
+ (i32.const 16)
+ )
+ )
+ (block
+ (local.set $x
+ (i32.const 1)
+ )
+ (local.set $y
+ (i32.const 1)
+ )
+ (local.set $z
+ (i32.const 1)
+ )
+ (local.set $w
+ (i32.const 1)
+ )
+ (block
+ (i32.store
+ (local.get $4)
+ (local.get $x)
+ )
+ (i32.store offset=4
+ (local.get $4)
+ (local.get $y)
+ )
+ (i32.store offset=8
+ (local.get $4)
+ (local.get $z)
+ )
+ (i32.store offset=12
+ (local.get $4)
+ (local.get $w)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (local.get $y)
+ )
+ (drop
+ (local.get $z)
+ )
+ (drop
+ (local.get $w)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $4)
+ )
+ )
+ (func $spill5
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local $a i32)
+ (local $5 i32)
+ (local.set $5
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $5)
+ (i32.const 32)
+ )
+ )
+ (block
+ (local.set $x
+ (i32.const 1)
+ )
+ (local.set $y
+ (i32.const 1)
+ )
+ (local.set $z
+ (i32.const 1)
+ )
+ (local.set $w
+ (i32.const 1)
+ )
+ (local.set $a
+ (i32.const 1)
+ )
+ (block
+ (i32.store
+ (local.get $5)
+ (local.get $x)
+ )
+ (i32.store offset=4
+ (local.get $5)
+ (local.get $y)
+ )
+ (i32.store offset=8
+ (local.get $5)
+ (local.get $z)
+ )
+ (i32.store offset=12
+ (local.get $5)
+ (local.get $w)
+ )
+ (i32.store offset=16
+ (local.get $5)
+ (local.get $a)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (local.get $y)
+ )
+ (drop
+ (local.get $z)
+ )
+ (drop
+ (local.get $w)
+ )
+ (drop
+ (local.get $a)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $5)
+ )
+ )
+ (func $some-alive
+ (local $x i32)
+ (local $y i32)
+ (local $2 i32)
+ (local.set $2
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $2)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (i32.store
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $2)
+ )
+ )
+ (func $spill-args (param $p i32) (param $q i32)
+ (local $x i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local.set $3
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $3)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $4
+ (i32.const 1)
+ )
+ (local.set $5
+ (i32.const 2)
+ )
+ (i32.store offset=8
+ (local.get $3)
+ (local.get $x)
+ )
+ (call $spill-args
+ (local.get $4)
+ (local.get $5)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $3)
+ )
+ )
+ (func $spill-ret (result i32)
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (local.set $4
+ (block (result i32)
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (if
+ (i32.const 1)
+ (block
+ (local.set $2
+ (i32.const 2)
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (local.get $2)
+ )
+ )
+ (block
+ (local.set $3
+ (i32.const 3)
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (local.get $3)
+ )
+ )
+ )
+ (i32.const 4)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (local.get $4)
+ )
+ (func $spill-unreachable (result i32)
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (local.set $2
+ (block (result i32)
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (unreachable)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (local.get $2)
+ )
+ (func $spill-call-call0 (param $p i32) (result i32)
+ (unreachable)
+ )
+ (func $spill-call-call1 (param $p i32) (result i32)
+ (local $x i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local.set $2
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $2)
+ (i32.const 16)
+ )
+ )
+ (local.set $5
+ (block (result i32)
+ (drop
+ (block (result i32)
+ (local.set $3
+ (block (result i32)
+ (local.set $4
+ (i32.const 1)
+ )
+ (i32.store offset=4
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $spill-call-call1
+ (local.get $4)
+ )
+ )
+ )
+ (i32.store offset=4
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $spill-call-call0
+ (local.get $3)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $2)
+ )
+ (local.get $5)
+ )
+ (func $spill-call-ret (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (call $spill-call-call0
+ (return
+ (i32.const 1)
+ )
+ )
+ )
+ (i32.const 0)
+ )
+ (func $spill-ret-call (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (return
+ (call $spill-call-call0
+ (i32.const 1)
+ )
+ )
+ )
+ (i32.const 0)
+ )
+ (func $spill-ret-ret (result i32)
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (local.set $3
+ (block (result i32)
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (block
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (block
+ (local.set $2
+ (i32.const 1)
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (local.get $2)
+ )
+ )
+ )
+ )
+ )
+ (i32.const 0)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (local.get $3)
+ )
+ (func $spill-call-othertype (param $y f64)
+ (local $x i32)
+ (local $2 i32)
+ (local $3 f64)
+ (local.set $2
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $2)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $3
+ (f64.const 1)
+ )
+ (i32.store
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $spill-call-othertype
+ (local.get $3)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $2)
+ )
+ )
+ (func $spill-call_indirect
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $2
+ (i32.const 123)
+ )
+ (local.set $3
+ (i32.const 456)
+ )
+ (local.set $4
+ (i32.const 789)
+ )
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call_indirect (type $ii)
+ (local.get $2)
+ (local.get $3)
+ (local.get $4)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ )
+ (func $spill-call_import
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $2
+ (i32.const 200)
+ )
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $segfault
+ (local.get $2)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ )
+)
+(module
+ (type $none_=>_none (func))
+ (type $none_=>_i32 (func (result i32)))
+ (type $i32_=>_i32 (func (param i32) (result i32)))
+ (type $ii (func (param i32 i32)))
+ (type $i32_=>_none (func (param i32)))
+ (type $f64_=>_none (func (param f64)))
+ (import "env" "segfault" (func $segfault (param i32)))
+ (global $stack_ptr (mut i32) (i32.const 1716592))
+ (memory $0 10)
+ (table $0 1 1 funcref)
+ (elem (i32.const 0))
+ (export "stackSave" (func $stack_save))
+ (func $stack_save (result i32)
+ (global.get $stack_ptr)
+ )
+ (func $nothing
+ (nop)
+ )
+ (func $not-alive
+ (local $x i32)
+ (local.set $x
+ (i32.const 1)
+ )
+ (call $nothing)
+ )
+ (func $spill
+ (local $x i32)
+ (local $1 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ )
+ (func $ignore-non-pointers
+ (local $x i32)
+ (local $y i64)
+ (local $z f32)
+ (local $w f64)
+ (local $4 i32)
+ (local.set $4
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $4)
+ (i32.const 16)
+ )
+ )
+ (block
+ (local.set $x
+ (i32.const 1)
+ )
+ (local.set $y
+ (i64.const 1)
+ )
+ (local.set $z
+ (f32.const 1)
+ )
+ (local.set $w
+ (f64.const 1)
+ )
+ (block
+ (i32.store
+ (local.get $4)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (local.get $y)
+ )
+ (drop
+ (local.get $z)
+ )
+ (drop
+ (local.get $w)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $4)
+ )
+ )
+ (func $spill4
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local $4 i32)
+ (local.set $4
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $4)
+ (i32.const 16)
+ )
+ )
+ (block
+ (local.set $x
+ (i32.const 1)
+ )
+ (local.set $y
+ (i32.const 1)
+ )
+ (local.set $z
+ (i32.const 1)
+ )
+ (local.set $w
+ (i32.const 1)
+ )
+ (block
+ (i32.store
+ (local.get $4)
+ (local.get $x)
+ )
+ (i32.store offset=4
+ (local.get $4)
+ (local.get $y)
+ )
+ (i32.store offset=8
+ (local.get $4)
+ (local.get $z)
+ )
+ (i32.store offset=12
+ (local.get $4)
+ (local.get $w)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (local.get $y)
+ )
+ (drop
+ (local.get $z)
+ )
+ (drop
+ (local.get $w)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $4)
+ )
+ )
+ (func $spill5
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local $a i32)
+ (local $5 i32)
+ (local.set $5
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $5)
+ (i32.const 32)
+ )
+ )
+ (block
+ (local.set $x
+ (i32.const 1)
+ )
+ (local.set $y
+ (i32.const 1)
+ )
+ (local.set $z
+ (i32.const 1)
+ )
+ (local.set $w
+ (i32.const 1)
+ )
+ (local.set $a
+ (i32.const 1)
+ )
+ (block
+ (i32.store
+ (local.get $5)
+ (local.get $x)
+ )
+ (i32.store offset=4
+ (local.get $5)
+ (local.get $y)
+ )
+ (i32.store offset=8
+ (local.get $5)
+ (local.get $z)
+ )
+ (i32.store offset=12
+ (local.get $5)
+ (local.get $w)
+ )
+ (i32.store offset=16
+ (local.get $5)
+ (local.get $a)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (local.get $y)
+ )
+ (drop
+ (local.get $z)
+ )
+ (drop
+ (local.get $w)
+ )
+ (drop
+ (local.get $a)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $5)
+ )
+ )
+ (func $some-alive
+ (local $x i32)
+ (local $y i32)
+ (local $2 i32)
+ (local.set $2
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $2)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (i32.store
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $2)
+ )
+ )
+ (func $spill-args (param $p i32) (param $q i32)
+ (local $x i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local.set $3
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $3)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $4
+ (i32.const 1)
+ )
+ (local.set $5
+ (i32.const 2)
+ )
+ (i32.store offset=8
+ (local.get $3)
+ (local.get $x)
+ )
+ (call $spill-args
+ (local.get $4)
+ (local.get $5)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $3)
+ )
+ )
+ (func $spill-ret (result i32)
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (local.set $4
+ (block (result i32)
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (if
+ (i32.const 1)
+ (block
+ (local.set $2
+ (i32.const 2)
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (local.get $2)
+ )
+ )
+ (block
+ (local.set $3
+ (i32.const 3)
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (local.get $3)
+ )
+ )
+ )
+ (i32.const 4)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (local.get $4)
+ )
+ (func $spill-unreachable (result i32)
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (local.set $2
+ (block (result i32)
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (unreachable)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (local.get $2)
+ )
+ (func $spill-call-call0 (param $p i32) (result i32)
+ (unreachable)
+ )
+ (func $spill-call-call1 (param $p i32) (result i32)
+ (local $x i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local.set $2
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $2)
+ (i32.const 16)
+ )
+ )
+ (local.set $5
+ (block (result i32)
+ (drop
+ (block (result i32)
+ (local.set $3
+ (block (result i32)
+ (local.set $4
+ (i32.const 1)
+ )
+ (i32.store offset=4
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $spill-call-call1
+ (local.get $4)
+ )
+ )
+ )
+ (i32.store offset=4
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $spill-call-call0
+ (local.get $3)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $2)
+ )
+ (local.get $5)
+ )
+ (func $spill-call-ret (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (call $spill-call-call0
+ (return
+ (i32.const 1)
+ )
+ )
+ )
+ (i32.const 0)
+ )
+ (func $spill-ret-call (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (return
+ (call $spill-call-call0
+ (i32.const 1)
+ )
+ )
+ )
+ (i32.const 0)
+ )
+ (func $spill-ret-ret (result i32)
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (local.set $3
+ (block (result i32)
+ (block
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $nothing)
+ )
+ (drop
+ (local.get $x)
+ )
+ (drop
+ (block
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (block
+ (local.set $2
+ (i32.const 1)
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (return
+ (local.get $2)
+ )
+ )
+ )
+ )
+ )
+ (i32.const 0)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ (local.get $3)
+ )
+ (func $spill-call-othertype (param $y f64)
+ (local $x i32)
+ (local $2 i32)
+ (local $3 f64)
+ (local.set $2
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $2)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $3
+ (f64.const 1)
+ )
+ (i32.store
+ (local.get $2)
+ (local.get $x)
+ )
+ (call $spill-call-othertype
+ (local.get $3)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $2)
+ )
+ )
+ (func $spill-call_indirect
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $2
+ (i32.const 123)
+ )
+ (local.set $3
+ (i32.const 456)
+ )
+ (local.set $4
+ (i32.const 789)
+ )
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call_indirect (type $ii)
+ (local.get $2)
+ (local.get $3)
+ (local.get $4)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ )
+ (func $spill-call_import
+ (local $x i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local.set $1
+ (global.get $stack_ptr)
+ )
+ (global.set $stack_ptr
+ (i32.sub
+ (local.get $1)
+ (i32.const 16)
+ )
+ )
+ (block
+ (block
+ (local.set $2
+ (i32.const 200)
+ )
+ (i32.store
+ (local.get $1)
+ (local.get $x)
+ )
+ (call $segfault
+ (local.get $2)
+ )
+ )
+ (drop
+ (local.get $x)
+ )
+ )
+ (global.set $stack_ptr
+ (local.get $1)
+ )
+ )
+)
diff --git a/test/passes/spill-pointers.wast b/test/passes/spill-pointers.wast
new file mode 100644
index 000000000..4eb05a721
--- /dev/null
+++ b/test/passes/spill-pointers.wast
@@ -0,0 +1,338 @@
+(module
+ (memory 10)
+ (type $ii (func (param i32 i32)))
+ (table 1 1 funcref)
+ (elem (i32.const 0))
+ (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32))
+ (import "env" "segfault" (func $segfault (param i32)))
+ (global $stack_ptr (mut i32) (global.get $STACKTOP$asm2wasm$import))
+
+ (func $nothing
+ )
+ (func $not-alive
+ (local $x i32)
+ (local.set $x (i32.const 1))
+ (call $nothing)
+ )
+ (func $spill
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ )
+ (func $ignore-non-pointers
+ (local $x i32)
+ (local $y i64)
+ (local $z f32)
+ (local $w f64)
+ (local.set $x (i32.const 1))
+ (local.set $y (i64.const 1))
+ (local.set $z (f32.const 1))
+ (local.set $w (f64.const 1))
+ (call $nothing)
+ (drop (local.get $x))
+ (drop (local.get $y))
+ (drop (local.get $z))
+ (drop (local.get $w))
+ )
+ (func $spill4
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local.set $x (i32.const 1))
+ (local.set $y (i32.const 1))
+ (local.set $z (i32.const 1))
+ (local.set $w (i32.const 1))
+ (call $nothing)
+ (drop (local.get $x))
+ (drop (local.get $y))
+ (drop (local.get $z))
+ (drop (local.get $w))
+ )
+ (func $spill5
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local $a i32)
+ (local.set $x (i32.const 1))
+ (local.set $y (i32.const 1))
+ (local.set $z (i32.const 1))
+ (local.set $w (i32.const 1))
+ (local.set $a (i32.const 1))
+ (call $nothing)
+ (drop (local.get $x))
+ (drop (local.get $y))
+ (drop (local.get $z))
+ (drop (local.get $w))
+ (drop (local.get $a))
+ )
+ (func $some-alive
+ (local $x i32)
+ (local $y i32)
+ (call $nothing)
+ (drop (local.get $x))
+ )
+ (func $spill-args (param $p i32) (param $q i32)
+ (local $x i32)
+ (call $spill-args (i32.const 1) (i32.const 2))
+ (drop (local.get $x))
+ )
+ (func $spill-ret (result i32)
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ (if (i32.const 1)
+ (return (i32.const 2))
+ (return (i32.const 3))
+ )
+ (i32.const 4)
+ )
+ (func $spill-unreachable (result i32)
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ (unreachable)
+ )
+ (func $spill-call-call0 (param $p i32) (result i32)
+ (unreachable)
+ )
+ (func $spill-call-call1 (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (call $spill-call-call0
+ (call $spill-call-call1
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-call-ret (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (call $spill-call-call0
+ (return
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-ret-call (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (return
+ (call $spill-call-call0
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-ret-ret (result i32)
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ (drop
+ (return
+ (return
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-call-othertype (param $y f64)
+ (local $x i32)
+ (call $spill-call-othertype (f64.const 1))
+ (drop (local.get $x))
+ )
+ (func $spill-call_indirect
+ (local $x i32)
+ (call_indirect (type $ii)
+ (i32.const 123)
+ (i32.const 456)
+ (i32.const 789)
+ )
+ (drop (local.get $x))
+ )
+ (func $spill-call_import
+ (local $x i32)
+ (call $segfault
+ (i32.const 200)
+ )
+ (drop (local.get $x))
+ )
+)
+
+(module
+ (memory 10)
+ (type $ii (func (param i32 i32)))
+ (table 1 1 funcref)
+ (elem (i32.const 0))
+ (global $stack_ptr (mut i32) (i32.const 1716592))
+ (export "stackSave" (func $stack_save))
+ (import "env" "segfault" (func $segfault (param i32)))
+ (func $stack_save (result i32)
+ (global.get $stack_ptr)
+ )
+
+ (func $nothing
+ )
+ (func $not-alive
+ (local $x i32)
+ (local.set $x (i32.const 1))
+ (call $nothing)
+ )
+ (func $spill
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ )
+ (func $ignore-non-pointers
+ (local $x i32)
+ (local $y i64)
+ (local $z f32)
+ (local $w f64)
+ (local.set $x (i32.const 1))
+ (local.set $y (i64.const 1))
+ (local.set $z (f32.const 1))
+ (local.set $w (f64.const 1))
+ (call $nothing)
+ (drop (local.get $x))
+ (drop (local.get $y))
+ (drop (local.get $z))
+ (drop (local.get $w))
+ )
+ (func $spill4
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local.set $x (i32.const 1))
+ (local.set $y (i32.const 1))
+ (local.set $z (i32.const 1))
+ (local.set $w (i32.const 1))
+ (call $nothing)
+ (drop (local.get $x))
+ (drop (local.get $y))
+ (drop (local.get $z))
+ (drop (local.get $w))
+ )
+ (func $spill5
+ (local $x i32)
+ (local $y i32)
+ (local $z i32)
+ (local $w i32)
+ (local $a i32)
+ (local.set $x (i32.const 1))
+ (local.set $y (i32.const 1))
+ (local.set $z (i32.const 1))
+ (local.set $w (i32.const 1))
+ (local.set $a (i32.const 1))
+ (call $nothing)
+ (drop (local.get $x))
+ (drop (local.get $y))
+ (drop (local.get $z))
+ (drop (local.get $w))
+ (drop (local.get $a))
+ )
+ (func $some-alive
+ (local $x i32)
+ (local $y i32)
+ (call $nothing)
+ (drop (local.get $x))
+ )
+ (func $spill-args (param $p i32) (param $q i32)
+ (local $x i32)
+ (call $spill-args (i32.const 1) (i32.const 2))
+ (drop (local.get $x))
+ )
+ (func $spill-ret (result i32)
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ (if (i32.const 1)
+ (return (i32.const 2))
+ (return (i32.const 3))
+ )
+ (i32.const 4)
+ )
+ (func $spill-unreachable (result i32)
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ (unreachable)
+ )
+ (func $spill-call-call0 (param $p i32) (result i32)
+ (unreachable)
+ )
+ (func $spill-call-call1 (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (call $spill-call-call0
+ (call $spill-call-call1
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-call-ret (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (call $spill-call-call0
+ (return
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-ret-call (param $p i32) (result i32)
+ (local $x i32)
+ (drop
+ (return
+ (call $spill-call-call0
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-ret-ret (result i32)
+ (local $x i32)
+ (call $nothing)
+ (drop (local.get $x))
+ (drop
+ (return
+ (return
+ (i32.const 1)
+ )
+ )
+ )
+ (local.get $x)
+ )
+ (func $spill-call-othertype (param $y f64)
+ (local $x i32)
+ (call $spill-call-othertype (f64.const 1))
+ (drop (local.get $x))
+ )
+ (func $spill-call_indirect
+ (local $x i32)
+ (call_indirect (type $ii)
+ (i32.const 123)
+ (i32.const 456)
+ (i32.const 789)
+ )
+ (drop (local.get $x))
+ )
+ (func $spill-call_import
+ (local $x i32)
+ (call $segfault
+ (i32.const 200)
+ )
+ (drop (local.get $x))
+ )
+)