summaryrefslogtreecommitdiff
path: root/test/lit/passes/optimize-instructions-gc.wast
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2022-12-21 11:47:48 -0600
committerGitHub <noreply@github.com>2022-12-21 09:47:48 -0800
commit49fb2e23bb3c932389f23fdda33a32d034ca9a0c (patch)
treefbe18fa7d4809a59a0d9577fb723bf1873d8adeb /test/lit/passes/optimize-instructions-gc.wast
parent94a45c6aba605f0f7e0a2fac227a2dd7c03a391f (diff)
downloadbinaryen-49fb2e23bb3c932389f23fdda33a32d034ca9a0c.tar.gz
binaryen-49fb2e23bb3c932389f23fdda33a32d034ca9a0c.tar.bz2
binaryen-49fb2e23bb3c932389f23fdda33a32d034ca9a0c.zip
Support `ref.test null` (#5368)
This new variant of ref.test returns 1 if the input is null.
Diffstat (limited to 'test/lit/passes/optimize-instructions-gc.wast')
-rw-r--r--test/lit/passes/optimize-instructions-gc.wast149
1 files changed, 143 insertions, 6 deletions
diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast
index bd697419b..1bf72ae04 100644
--- a/test/lit/passes/optimize-instructions-gc.wast
+++ b/test/lit/passes/optimize-instructions-gc.wast
@@ -14,18 +14,18 @@
(field $i64 (mut i64))
))
+ ;; CHECK: (type $array (array (mut i8)))
+
;; CHECK: (type $A (struct (field i32)))
+ ;; NOMNL: (type $array (array (mut i8)))
+
;; NOMNL: (type $A (struct (field i32)))
(type $A (struct (field i32)))
- ;; CHECK: (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
-
- ;; CHECK: (type $array (array (mut i8)))
- ;; NOMNL: (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
-
- ;; NOMNL: (type $array (array (mut i8)))
(type $array (array (mut i8)))
+ ;; CHECK: (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
+ ;; NOMNL: (type $B (struct_subtype (field i32) (field i32) (field f32) $A))
(type $B (struct_subtype (field i32) (field i32) (field f32) $A))
;; CHECK: (type $B-child (struct_subtype (field i32) (field i32) (field f32) (field i64) $B))
@@ -1882,6 +1882,21 @@
;; CHECK-NEXT: (i32.const 0)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.test null $array
+ ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $struct)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $incompatible-test (type $ref?|$struct|_=>_none) (param $struct (ref null $struct))
;; NOMNL-NEXT: (drop
@@ -1892,6 +1907,21 @@
;; NOMNL-NEXT: (i32.const 0)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.test null $array
+ ;; NOMNL-NEXT: (local.get $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $struct)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 0)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $incompatible-test (param $struct (ref null $struct))
(drop
@@ -1900,6 +1930,20 @@
(local.get $struct)
)
)
+ (drop
+ ;; But this one might succeed due to a null, so don't optimize it.
+ (ref.test null $array
+ (local.get $struct)
+ )
+ )
+ (drop
+ ;; This one cannot succeed due to a null, so optimize it.
+ (ref.test null $array
+ (ref.as_non_null
+ (local.get $struct)
+ )
+ )
+ )
)
;; CHECK: (func $subtype-compatible (type $ref?|$A|_ref?|$B|_=>_none) (param $A (ref null $A)) (param $B (ref null $B))
@@ -1913,6 +1957,34 @@
;; CHECK-NEXT: (local.get $B)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (local.get $B)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $B)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (block (result i32)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (local.get $B)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $subtype-compatible (type $ref?|$A|_ref?|$B|_=>_none) (param $A (ref null $A)) (param $B (ref null $B))
;; NOMNL-NEXT: (drop
@@ -1925,6 +1997,34 @@
;; NOMNL-NEXT: (local.get $B)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (local.get $B)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $B)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (block (result i32)
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.as_non_null
+ ;; NOMNL-NEXT: (local.get $B)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (i32.const 1)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $subtype-compatible (param $A (ref null $A)) (param $B (ref null $B))
(drop
@@ -1939,6 +2039,28 @@
(local.get $B)
)
)
+ (drop
+ ;; If the test is nullable, this will succeed.
+ (ref.test null $A
+ (local.get $B)
+ )
+ )
+ (drop
+ ;; We will also succeed if the input is non-nullable.
+ (ref.test $A
+ (ref.as_non_null
+ (local.get $B)
+ )
+ )
+ )
+ (drop
+ ;; Or if the test is nullable and the input is non-nullable.
+ (ref.test null $A
+ (ref.as_non_null
+ (local.get $B)
+ )
+ )
+ )
)
;; CHECK: (func $ref.test-unreachable (type $ref?|$A|_=>_none) (param $A (ref null $A))
;; CHECK-NEXT: (drop
@@ -1946,6 +2068,11 @@
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (ref.test null $A
+ ;; CHECK-NEXT: (unreachable)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOMNL: (func $ref.test-unreachable (type $ref?|$A|_=>_none) (param $A (ref null $A))
;; NOMNL-NEXT: (drop
@@ -1953,6 +2080,11 @@
;; NOMNL-NEXT: (unreachable)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: (drop
+ ;; NOMNL-NEXT: (ref.test null $A
+ ;; NOMNL-NEXT: (unreachable)
+ ;; NOMNL-NEXT: )
+ ;; NOMNL-NEXT: )
;; NOMNL-NEXT: )
(func $ref.test-unreachable (param $A (ref null $A))
(drop
@@ -1962,6 +2094,11 @@
(unreachable)
)
)
+ (drop
+ (ref.test null $A
+ (unreachable)
+ )
+ )
)
;; CHECK: (func $consecutive-opts-with-unreachable (type $funcref_=>_none) (param $func funcref)