summaryrefslogtreecommitdiff
path: root/test/lit/passes
diff options
context:
space:
mode:
Diffstat (limited to 'test/lit/passes')
-rw-r--r--test/lit/passes/gto_and_cfp_in_O.wast28
-rw-r--r--test/lit/passes/remove-unused-module-elements-refs.wast184
2 files changed, 200 insertions, 12 deletions
diff --git a/test/lit/passes/gto_and_cfp_in_O.wast b/test/lit/passes/gto_and_cfp_in_O.wast
index a36bbc4ea..9d385d0f9 100644
--- a/test/lit/passes/gto_and_cfp_in_O.wast
+++ b/test/lit/passes/gto_and_cfp_in_O.wast
@@ -1,18 +1,37 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
-;; RUN: foreach %s %t wasm-opt -O -all --nominal -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt -O -all --nominal --closed-world -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt -O -all --nominal -S -o - | filecheck %s --check-prefix OPEN_WORLD
;; Test that -O, with nominal typing + GC enabled, will run global type
-;; optimization in conjunction with constant field propagation etc.
+;; optimization in conjunction with constant field propagation etc. But, in an
+;; open world we do not run them.
(module
+ ;; OPEN_WORLD: (type $struct (struct (field (mut funcref)) (field (mut i32))))
(type $struct (struct_subtype (field (mut funcref)) (field (mut i32)) data))
+ ;; OPEN_WORLD: (type $none_=>_none (func))
+
+ ;; OPEN_WORLD: (type $none_=>_i32 (func (result i32)))
+
+ ;; OPEN_WORLD: (global $glob (ref $struct) (struct.new $struct
+ ;; OPEN_WORLD-NEXT: (ref.func $by-ref)
+ ;; OPEN_WORLD-NEXT: (i32.const 100)
+ ;; OPEN_WORLD-NEXT: ))
(global $glob (ref $struct) (struct.new $struct
(ref.func $by-ref)
(i32.const 100)
))
+ ;; OPEN_WORLD: (export "main" (func $main))
+
+ ;; OPEN_WORLD: (func $by-ref (type $none_=>_none) (; has Stack IR ;)
+ ;; OPEN_WORLD-NEXT: (struct.set $struct 1
+ ;; OPEN_WORLD-NEXT: (global.get $glob)
+ ;; OPEN_WORLD-NEXT: (i32.const 200)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
(func $by-ref
;; This function is kept alive by the reference in $glob. After we remove
;; the field that the funcref is written to, we remove the funcref, which
@@ -33,6 +52,11 @@
;; CHECK: (func $main (type $none_=>_i32) (; has Stack IR ;) (result i32)
;; CHECK-NEXT: (i32.const 100)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $main (type $none_=>_i32) (; has Stack IR ;) (result i32)
+ ;; OPEN_WORLD-NEXT: (struct.get $struct 1
+ ;; OPEN_WORLD-NEXT: (global.get $glob)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
(func $main (export "main") (result i32)
;; After all the above optimizations, we can infer that $main should simply
;; return 100.
diff --git a/test/lit/passes/remove-unused-module-elements-refs.wast b/test/lit/passes/remove-unused-module-elements-refs.wast
index 1e23099b9..8e4ed70a7 100644
--- a/test/lit/passes/remove-unused-module-elements-refs.wast
+++ b/test/lit/passes/remove-unused-module-elements-refs.wast
@@ -1,12 +1,22 @@
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
-;; RUN: foreach %s %t wasm-opt --remove-unused-module-elements --nominal -all -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt --remove-unused-module-elements --closed-world --nominal -all -S -o - | filecheck %s
+;; RUN: foreach %s %t wasm-opt --remove-unused-module-elements --nominal -all -S -o - | filecheck %s --check-prefix OPEN_WORLD
+
+;; Test both open world (default) and closed world. In a closed world we can do
+;; more with function refs, as we assume nothing calls them on the outside, so
+;; if no calls exist to the right type, the function is not reached.
(module
;; CHECK: (type $A (func))
+ ;; OPEN_WORLD: (type $A (func))
(type $A (func))
+
;; CHECK: (type $ref?|$A|_=>_none (func (param (ref null $A))))
;; CHECK: (type $B (func))
+ ;; OPEN_WORLD: (type $ref?|$A|_=>_none (func (param (ref null $A))))
+
+ ;; OPEN_WORLD: (type $B (func))
(type $B (func))
;; CHECK: (elem declare func $target-A $target-B)
@@ -30,6 +40,27 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (elem declare func $target-A $target-B)
+
+ ;; OPEN_WORLD: (export "foo" (func $foo))
+
+ ;; OPEN_WORLD: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-B)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (call_ref $A
+ ;; OPEN_WORLD-NEXT: (local.get $A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (block ;; (replaces something unreachable we can't emit)
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (unreachable)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (unreachable)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
(func $foo (export "foo") (param $A (ref null $A))
;; This export has two RefFuncs, and one CallRef.
(drop
@@ -51,6 +82,9 @@
;; CHECK: (func $target-A (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-A (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-A (type $A)
;; This function is reachable from the export "foo": there is a RefFunc and
;; a CallRef for it there.
@@ -64,6 +98,9 @@
;; CHECK: (func $target-B (type $B)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-B (type $B)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-B (type $B)
;; This function is not reachable. We have a RefFunc in "foo" but no
;; suitable CallRef.
@@ -71,33 +108,51 @@
;; Note that we cannot remove the function, as the RefFunc must refer to
;; something in order to validate. But we can clear out the body of this
;; function with an unreachable.
+ ;;
+ ;; As mentioned above, in an open world we cannot optimize here, so the
+ ;; function body will remain empty as a nop, and not turn into an
+ ;; unreachable.
)
)
;; As above, but reverse the order inside $foo, so we see the CallRef first.
(module
;; CHECK: (type $A (func))
+ ;; OPEN_WORLD: (type $A (func))
(type $A (func))
(type $B (func))
+ ;; CHECK: (type $ref?|$A|_=>_none (func (param (ref null $A))))
+
;; CHECK: (elem declare func $target-A)
;; CHECK: (export "foo" (func $foo))
- ;; CHECK: (func $foo (type $A)
- ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit)
- ;; CHECK-NEXT: (drop
- ;; CHECK-NEXT: (ref.null nofunc)
- ;; CHECK-NEXT: )
- ;; CHECK-NEXT: (unreachable)
+ ;; CHECK: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
+ ;; CHECK-NEXT: (call_ref $A
+ ;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (ref.func $target-A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- (func $foo (export "foo")
+ ;; OPEN_WORLD: (type $ref?|$A|_=>_none (func (param (ref null $A))))
+
+ ;; OPEN_WORLD: (elem declare func $target-A)
+
+ ;; OPEN_WORLD: (export "foo" (func $foo))
+
+ ;; OPEN_WORLD: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
+ ;; OPEN_WORLD-NEXT: (call_ref $A
+ ;; OPEN_WORLD-NEXT: (local.get $A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
+ (func $foo (export "foo") (param $A (ref null $A))
(call_ref $A
- (ref.null $A)
+ (local.get $A)
)
(drop
(ref.func $target-A)
@@ -105,8 +160,11 @@
)
;; CHECK: (func $target-A (type $A)
- ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-A (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-A (type $A)
;; This function is reachable.
)
@@ -119,6 +177,7 @@
;; As above, but interleave CallRefs with RefFuncs.
(module
;; CHECK: (type $A (func))
+ ;; OPEN_WORLD: (type $A (func))
(type $A (func))
(type $B (func))
@@ -142,6 +201,26 @@
;; CHECK-NEXT: (ref.func $target-A-2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (type $ref?|$A|_=>_none (func (param (ref null $A))))
+
+ ;; OPEN_WORLD: (elem declare func $target-A-1 $target-A-2)
+
+ ;; OPEN_WORLD: (export "foo" (func $foo))
+
+ ;; OPEN_WORLD: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
+ ;; OPEN_WORLD-NEXT: (call_ref $A
+ ;; OPEN_WORLD-NEXT: (local.get $A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-A-1)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (call_ref $A
+ ;; OPEN_WORLD-NEXT: (local.get $A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-A-2)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
(func $foo (export "foo") (param $A (ref null $A))
(call_ref $A
(local.get $A)
@@ -160,6 +239,9 @@
;; CHECK: (func $target-A-1 (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-A-1 (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-A-1 (type $A)
;; This function is reachable.
)
@@ -167,6 +249,9 @@
;; CHECK: (func $target-A-2 (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-A-2 (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-A-2 (type $A)
;; This function is reachable.
)
@@ -180,6 +265,7 @@
;; same.
(module
;; CHECK: (type $A (func))
+ ;; OPEN_WORLD: (type $A (func))
(type $A (func))
(type $B (func))
@@ -203,6 +289,26 @@
;; CHECK-NEXT: (local.get $A)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (type $ref?|$A|_=>_none (func (param (ref null $A))))
+
+ ;; OPEN_WORLD: (elem declare func $target-A-1 $target-A-2)
+
+ ;; OPEN_WORLD: (export "foo" (func $foo))
+
+ ;; OPEN_WORLD: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-A-1)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (call_ref $A
+ ;; OPEN_WORLD-NEXT: (local.get $A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-A-2)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (call_ref $A
+ ;; OPEN_WORLD-NEXT: (local.get $A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
(func $foo (export "foo") (param $A (ref null $A))
(drop
(ref.func $target-A-1)
@@ -221,6 +327,9 @@
;; CHECK: (func $target-A-1 (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-A-1 (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-A-1 (type $A)
;; This function is reachable.
)
@@ -228,6 +337,9 @@
;; CHECK: (func $target-A-2 (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-A-2 (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-A-2 (type $A)
;; This function is reachable.
)
@@ -241,15 +353,20 @@
;; but for now other imports do not (until we add a flag for closed-world).
(module
;; CHECK: (type $A (func))
+ ;; OPEN_WORLD: (type $A (func))
(type $A (func))
;; CHECK: (type $funcref_=>_none (func (param funcref)))
;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param funcref)))
+ ;; OPEN_WORLD: (type $funcref_=>_none (func (param funcref)))
+
+ ;; OPEN_WORLD: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param funcref)))
(import "binaryen-intrinsics" "call.without.effects"
(func $call-without-effects (param funcref)))
;; CHECK: (import "other" "import" (func $other-import (param funcref)))
+ ;; OPEN_WORLD: (import "other" "import" (func $other-import (param funcref)))
(import "other" "import"
(func $other-import (param funcref)))
@@ -265,6 +382,18 @@
;; CHECK-NEXT: (ref.func $target-drop)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (elem declare func $target-drop $target-keep)
+
+ ;; OPEN_WORLD: (export "foo" (func $foo))
+
+ ;; OPEN_WORLD: (func $foo (type $A)
+ ;; OPEN_WORLD-NEXT: (call $call-without-effects
+ ;; OPEN_WORLD-NEXT: (ref.func $target-keep)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (call $other-import
+ ;; OPEN_WORLD-NEXT: (ref.func $target-drop)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
(func $foo (export "foo")
;; Calling the intrinsic with a reference is considered a call of the
;; reference, so we will not remove $target-keep.
@@ -280,13 +409,20 @@
;; CHECK: (func $target-keep (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-keep (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-keep (type $A)
)
;; CHECK: (func $target-drop (type $A)
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-drop (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-drop (type $A)
+ ;; In a closed world we can turn this body into unreachable.
)
)
@@ -294,6 +430,7 @@
;; function being called.
(module
;; CHECK: (type $A (func))
+ ;; OPEN_WORLD: (type $A (func))
(type $A (func))
;; CHECK: (type $funcref_=>_none (func (param funcref)))
@@ -301,10 +438,16 @@
;; CHECK: (type $ref?|$A|_=>_none (func (param (ref null $A))))
;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param funcref)))
+ ;; OPEN_WORLD: (type $funcref_=>_none (func (param funcref)))
+
+ ;; OPEN_WORLD: (type $ref?|$A|_=>_none (func (param (ref null $A))))
+
+ ;; OPEN_WORLD: (import "binaryen-intrinsics" "call.without.effects" (func $call-without-effects (param funcref)))
(import "binaryen-intrinsics" "call.without.effects"
(func $call-without-effects (param funcref)))
;; CHECK: (import "other" "import" (func $other-import (param funcref)))
+ ;; OPEN_WORLD: (import "other" "import" (func $other-import (param funcref)))
(import "other" "import"
(func $other-import (param funcref)))
@@ -323,6 +466,21 @@
;; CHECK-NEXT: (ref.func $target-keep-2)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (elem declare func $target-keep $target-keep-2)
+
+ ;; OPEN_WORLD: (export "foo" (func $foo))
+
+ ;; OPEN_WORLD: (func $foo (type $ref?|$A|_=>_none) (param $A (ref null $A))
+ ;; OPEN_WORLD-NEXT: (call $call-without-effects
+ ;; OPEN_WORLD-NEXT: (local.get $A)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (ref.func $target-keep)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: (call $other-import
+ ;; OPEN_WORLD-NEXT: (ref.func $target-keep-2)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
(func $foo (export "foo") (param $A (ref null $A))
;; Call the intrinsic without a RefFunc. All we infer here is the type,
;; which means we must assume anything with type $A (and a reference) can be
@@ -341,12 +499,18 @@
;; CHECK: (func $target-keep (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-keep (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-keep (type $A)
)
;; CHECK: (func $target-keep-2 (type $A)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $target-keep-2 (type $A)
+ ;; OPEN_WORLD-NEXT: (nop)
+ ;; OPEN_WORLD-NEXT: )
(func $target-keep-2 (type $A)
)
)