summaryrefslogtreecommitdiff
path: root/test/lit
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit')
-rw-r--r--test/lit/passes/signature-pruning.wast195
1 files changed, 193 insertions, 2 deletions
diff --git a/test/lit/passes/signature-pruning.wast b/test/lit/passes/signature-pruning.wast
index 86a26130c..3c27ee874 100644
--- a/test/lit/passes/signature-pruning.wast
+++ b/test/lit/passes/signature-pruning.wast
@@ -356,11 +356,14 @@
)
;; CHECK: (func $caller (type $none_=>_none)
+ ;; CHECK-NEXT: (local $x i32)
;; CHECK-NEXT: (call $foo)
;; CHECK-NEXT: )
(func $caller
+ (local $x i32)
(call $foo
- (i32.const 0)
+ ;; (avoid passing in a constant value to avoid other opts kicking in)
+ (local.get $x)
)
)
)
@@ -556,18 +559,40 @@
)
)
-;; Exports cannot be optimized.
+;; Exports cannot be optimized in any way: we cannot remove parameters from
+;; them, and also we cannot apply constant parameter values either.
(module
;; CHECK: (type $sig (func_subtype (param i32) func))
(type $sig (func_subtype (param i32) func))
+ ;; CHECK: (type $none_=>_none (func_subtype func))
+
;; CHECK: (export "foo" (func $foo))
+ ;; CHECK: (export "bar" (func $bar))
+
;; CHECK: (func $foo (type $sig) (param $i32 i32)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $foo (export "foo") (type $sig) (param $i32 i32)
)
+
+ ;; CHECK: (func $bar (type $sig) (param $i32 i32)
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: )
+ (func $bar (export "bar") (type $sig) (param $i32 i32)
+ )
+
+ ;; CHECK: (func $call-bar (type $none_=>_none)
+ ;; CHECK-NEXT: (call $bar
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $call-bar
+ (call $bar
+ (i32.const 42)
+ )
+ )
)
;; Two functions with two different types have an unused parameter. After
@@ -595,3 +620,169 @@
)
)
+(module
+ ;; CHECK: (type $sig-foo (func_subtype func))
+ (type $sig-foo (func_subtype (param i32) func))
+ ;; CHECK: (type $sig-bar (func_subtype (param i32) func))
+ (type $sig-bar (func_subtype (param i32) func))
+
+ (memory 1 1)
+
+ ;; CHECK: (memory $0 1 1)
+
+ ;; CHECK: (func $foo (type $sig-foo)
+ ;; CHECK-NEXT: (local $0 i32)
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (i32.store
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo (type $sig-foo) (param $i32 i32)
+ ;; This function is always called with the same constant, and we can
+ ;; apply that constant here and prune the param.
+ (i32.store
+ (i32.const 0)
+ (local.get $i32)
+ )
+ (call $foo (i32.const 42))
+ (call $foo (i32.const 42))
+ (call $foo (i32.const 42))
+ )
+
+ ;; CHECK: (func $bar (type $sig-bar) (param $i32 i32)
+ ;; CHECK-NEXT: (i32.store
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (local.get $i32)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $bar
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $bar
+ ;; CHECK-NEXT: (i32.const 43)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (type $sig-bar) (param $i32 i32)
+ ;; This function is called with various values, and cannot be optimized like
+ ;; the previous one.
+ (i32.store
+ (i32.const 0)
+ (local.get $i32)
+ )
+ (call $bar (i32.const 42))
+ (call $bar (i32.const 43))
+ )
+)
+
+;; As above, but $foo's parameter is a ref.func, which is also a constant
+;; value that we can optimize in the case of $foo (but not $bar, again, as $bar
+;; is not always sent a constant value).
+(module
+ ;; CHECK: (type $sig-foo (func_subtype func))
+ (type $sig-foo (func_subtype (param funcref) func))
+ ;; CHECK: (type $sig-bar (func_subtype (param funcref) func))
+ (type $sig-bar (func_subtype (param funcref) func))
+
+ (memory 1 1)
+
+ ;; CHECK: (memory $0 1 1)
+
+ ;; CHECK: (elem declare func $bar $foo)
+
+ ;; CHECK: (func $foo (type $sig-foo)
+ ;; CHECK-NEXT: (local $0 funcref)
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (ref.func $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo (type $sig-foo) (param $funcref funcref)
+ (drop (local.get $funcref))
+ (call $foo (ref.func $foo))
+ (call $foo (ref.func $foo))
+ (call $foo (ref.func $foo))
+ )
+
+ ;; CHECK: (func $bar (type $sig-bar) (param $funcref funcref)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $funcref)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $bar
+ ;; CHECK-NEXT: (ref.func $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $bar
+ ;; CHECK-NEXT: (ref.func $bar)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (type $sig-bar) (param $funcref funcref)
+ (drop (local.get $funcref))
+ (call $bar (ref.func $foo))
+ (call $bar (ref.func $bar))
+ )
+)
+
+;; As above, but the values are now ref.nulls. All nulls compare equal, so we
+;; can still optimize even though the types differ.
+(module
+ ;; CHECK: (type $sig-foo (func_subtype func))
+ (type $sig-foo (func_subtype (param anyref) func))
+ ;; CHECK: (type $sig-bar (func_subtype (param anyref) func))
+ (type $sig-bar (func_subtype (param anyref) func))
+
+ (memory 1 1)
+
+ ;; CHECK: (memory $0 1 1)
+
+ ;; CHECK: (elem declare func $foo)
+
+ ;; CHECK: (func $foo (type $sig-foo)
+ ;; CHECK-NEXT: (local $0 anyref)
+ ;; CHECK-NEXT: (local.set $0
+ ;; CHECK-NEXT: (ref.null any)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (block
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: (call $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $foo (type $sig-foo) (param $anyref anyref)
+ (drop (local.get $anyref))
+ (call $foo (ref.null any))
+ (call $foo (ref.null func))
+ )
+
+ ;; CHECK: (func $bar (type $sig-bar) (param $anyref anyref)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $anyref)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $bar
+ ;; CHECK-NEXT: (ref.func $foo)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (call $bar
+ ;; CHECK-NEXT: (ref.null func)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $bar (type $sig-bar) (param $anyref anyref)
+ (drop (local.get $anyref))
+ ;; Mixing a null with something else prevents optimization, of course.
+ (call $bar (ref.func $foo))
+ (call $bar (ref.null func))
+ )
+)