summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-02-02 12:08:42 -0800
committerGitHub <noreply@github.com>2023-02-02 12:08:42 -0800
commit91f54df07766a5884203aa1fcfd6b0d61a3eb142 (patch)
tree82e85642ed86b0033dbf5b472710fb8f934baf7c /test
parentd1b75970e5425a5e8b08ca87801d1343df43fde7 (diff)
downloadbinaryen-91f54df07766a5884203aa1fcfd6b0d61a3eb142.tar.gz
binaryen-91f54df07766a5884203aa1fcfd6b0d61a3eb142.tar.bz2
binaryen-91f54df07766a5884203aa1fcfd6b0d61a3eb142.zip
[Wasm GC] Fix RemoveUnusedModuleEffects struct field reads with call.without.effects (#5477)
If we see (struct.new $A (call $call.without.effects ;; intrinsic (ref.func $getter) ) ) then we can ignore side effects in that call, as the intrinsic tells us to. However, that function is still called (it will be called normally, after intrinsics are lowered away), and we should not remove it. That is, such an intrinsic call can be removed, but it cannot be left as it is and also ignored as if it does not exist.
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/remove-unused-module-elements-refs.wast73
1 files changed, 73 insertions, 0 deletions
diff --git a/test/lit/passes/remove-unused-module-elements-refs.wast b/test/lit/passes/remove-unused-module-elements-refs.wast
index 2bbba0cad..61ccb4daf 100644
--- a/test/lit/passes/remove-unused-module-elements-refs.wast
+++ b/test/lit/passes/remove-unused-module-elements-refs.wast
@@ -1841,3 +1841,76 @@
(func $f (type $void)
)
)
+
+;; The call.without.effects intrinsic reports itself as having no side effects.
+;; We do still need to consider the target as being called, however, even if it
+;; is in a struct field.
+(module
+ ;; CHECK: (type $funcref_=>_i32 (func (param funcref) (result i32)))
+
+ ;; CHECK: (type $none_=>_none (func))
+
+ ;; CHECK: (type $A (struct (field i32)))
+ ;; OPEN_WORLD: (type $funcref_=>_i32 (func (param funcref) (result i32)))
+
+ ;; OPEN_WORLD: (type $none_=>_none (func))
+
+ ;; OPEN_WORLD: (type $A (struct (field i32)))
+ (type $A (struct (field i32)))
+
+ ;; CHECK: (type $none_=>_i32 (func (result i32)))
+
+ ;; CHECK: (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects (param funcref) (result i32)))
+ ;; OPEN_WORLD: (type $none_=>_i32 (func (result i32)))
+
+ ;; OPEN_WORLD: (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects (param funcref) (result i32)))
+ (import "binaryen-intrinsics" "call.without.effects" (func $call.without.effects (param funcref) (result i32)))
+
+ ;; CHECK: (elem declare func $getter)
+
+ ;; CHECK: (export "main" (func $main))
+
+ ;; CHECK: (func $main (type $none_=>_none)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (struct.new $A
+ ;; CHECK-NEXT: (call $call.without.effects
+ ;; CHECK-NEXT: (ref.func $getter)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (elem declare func $getter)
+
+ ;; OPEN_WORLD: (export "main" (func $main))
+
+ ;; OPEN_WORLD: (func $main (type $none_=>_none)
+ ;; OPEN_WORLD-NEXT: (drop
+ ;; OPEN_WORLD-NEXT: (struct.new $A
+ ;; OPEN_WORLD-NEXT: (call $call.without.effects
+ ;; OPEN_WORLD-NEXT: (ref.func $getter)
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
+ ;; OPEN_WORLD-NEXT: )
+ (func $main (export "main")
+ (drop
+ (struct.new $A
+ (call $call.without.effects
+ (ref.func $getter)
+ )
+ )
+ )
+ )
+
+ ;; CHECK: (func $getter (type $none_=>_i32) (result i32)
+ ;; CHECK-NEXT: (i32.const 42)
+ ;; CHECK-NEXT: )
+ ;; OPEN_WORLD: (func $getter (type $none_=>_i32) (result i32)
+ ;; OPEN_WORLD-NEXT: (i32.const 42)
+ ;; OPEN_WORLD-NEXT: )
+ (func $getter (result i32)
+ ;; This function body should not be turned into an unreachable. It is
+ ;; reached from $main, even though the call is marked as not having effects.
+ (i32.const 42)
+ )
+)