summaryrefslogtreecommitdiff
path: root/test/lit/passes
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-08-30 16:17:34 -0500
committerGitHub <noreply@github.com>2023-08-30 14:17:34 -0700
commit2cdc61f04ef33c5f2055f54d88dee68110a42850 (patch)
tree3e603b973abb3526a9888eb417ffbf91d3330066 /test/lit/passes
parentaceaa3582c8a4d6d6084e1087a79ae0bc488f8b7 (diff)
downloadbinaryen-2cdc61f04ef33c5f2055f54d88dee68110a42850.tar.gz
binaryen-2cdc61f04ef33c5f2055f54d88dee68110a42850.tar.bz2
binaryen-2cdc61f04ef33c5f2055f54d88dee68110a42850.zip
Validate and fix up tuples with non-nullable elements (#5909)
The code validating and fixing up non-nullable locals previously did not correctly handle tuples that contained non-nullable elements, which could have resulted in invalid modules going undetected. Update the code to handle tuples and add tests.
Diffstat (limited to 'test/lit/passes')
-rw-r--r--test/lit/passes/coalesce-locals-gc.wast141
-rw-r--r--test/lit/passes/simplify-locals-gc-nn.wast60
2 files changed, 189 insertions, 12 deletions
diff --git a/test/lit/passes/coalesce-locals-gc.wast b/test/lit/passes/coalesce-locals-gc.wast
index ae639c7f9..fdd2b0e60 100644
--- a/test/lit/passes/coalesce-locals-gc.wast
+++ b/test/lit/passes/coalesce-locals-gc.wast
@@ -1,12 +1,7 @@
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
-;; RUN: wasm-opt %s --remove-unused-names --coalesce-locals -all -S -o - \
+;; RUN: wasm-opt %s --coalesce-locals -all -S -o - \
;; RUN: | filecheck %s
-;; --remove-unused-names is run to avoid adding names to blocks. Block names
-;; can prevent non-nullable local validation (we emit named blocks in the binary
-;; format, if we need them, but never emit unnamed ones), which affects some
-;; testcases.
-
(module
;; CHECK: (type $A (struct (field structref)))
@@ -21,7 +16,16 @@
;; CHECK: (global $global (ref null $array) (ref.null none))
(global $global (ref null $array) (ref.null $array))
- ;; CHECK: (func $test-dead-get-non-nullable (type $5) (param $0 (ref struct))
+ ;; CHECK: (global $nn-tuple-global (mut ((ref any) i32)) (tuple.make
+ ;; CHECK-NEXT: (i31.new
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: ))
+ (global $nn-tuple-global (mut ((ref any) i32)) (tuple.make (i31.new (i32.const 0)) (i32.const 1)))
+
+
+ ;; CHECK: (func $test-dead-get-non-nullable (type $6) (param $0 (ref struct))
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (block (result (ref struct))
@@ -39,7 +43,7 @@
)
)
- ;; CHECK: (func $br_on_null (type $6) (param $0 (ref null $array)) (result (ref null $array))
+ ;; CHECK: (func $br_on_null (type $7) (param $0 (ref null $array)) (result (ref null $array))
;; CHECK-NEXT: (block $label$1 (result (ref null $array))
;; CHECK-NEXT: (block $label$2
;; CHECK-NEXT: (br $label$1
@@ -176,7 +180,7 @@
)
)
- ;; CHECK: (func $remove-tee-refinalize (type $4) (param $0 (ref null $A)) (param $1 (ref null $B)) (result structref)
+ ;; CHECK: (func $remove-tee-refinalize (type $5) (param $0 (ref null $A)) (param $1 (ref null $B)) (result structref)
;; CHECK-NEXT: (struct.get $A 0
;; CHECK-NEXT: (block (result (ref null $A))
;; CHECK-NEXT: (local.get $1)
@@ -197,7 +201,7 @@
)
)
- ;; CHECK: (func $remove-tee-refinalize-2 (type $4) (param $0 (ref null $A)) (param $1 (ref null $B)) (result structref)
+ ;; CHECK: (func $remove-tee-refinalize-2 (type $5) (param $0 (ref null $A)) (param $1 (ref null $B)) (result structref)
;; CHECK-NEXT: (struct.get $A 0
;; CHECK-NEXT: (block (result (ref null $A))
;; CHECK-NEXT: (local.get $1)
@@ -219,7 +223,7 @@
)
)
- ;; CHECK: (func $replace-i31-local (type $7) (result i32)
+ ;; CHECK: (func $replace-i31-local (type $8) (result i32)
;; CHECK-NEXT: (local $0 i31ref)
;; CHECK-NEXT: (i32.add
;; CHECK-NEXT: (unreachable)
@@ -251,7 +255,7 @@
)
)
- ;; CHECK: (func $replace-struct-param (type $8) (param $0 f64) (param $1 (ref null $A)) (result f32)
+ ;; CHECK: (func $replace-struct-param (type $9) (param $0 f64) (param $1 (ref null $A)) (result f32)
;; CHECK-NEXT: (call $replace-struct-param
;; CHECK-NEXT: (block (result f64)
;; CHECK-NEXT: (unreachable)
@@ -278,4 +282,117 @@
)
)
)
+
+ ;; CHECK: (func $test (type $10) (param $0 (ref any)) (result (ref any) i32)
+ ;; CHECK-NEXT: (local $1 (anyref i32))
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (if
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (local.get $0)
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (global.set $nn-tuple-global
+ ;; CHECK-NEXT: (block (result (ref any) i32)
+ ;; CHECK-NEXT: (local.set $1
+ ;; CHECK-NEXT: (if (result (ref any) i32)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (tuple.extract 0
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.extract 1
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (tuple.extract 0
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.extract 1
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (tuple.extract 0
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.extract 1
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (tuple.extract 0
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.extract 1
+ ;; CHECK-NEXT: (local.get $1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test (param $any (ref any)) (result (ref any) i32)
+ (local $x ((ref any) i32))
+ (local $y ((ref any) i32))
+ ;; This store is dead and will be removed.
+ (local.set $x
+ (tuple.make
+ (local.get $any)
+ (i32.const 0)
+ )
+ )
+ (if
+ (i32.const 0)
+ ;; These two sets will remain.
+ (local.set $x
+ (tuple.make
+ (local.get $any)
+ (i32.const 1)
+ )
+ )
+ (local.set $x
+ (tuple.make
+ (local.get $any)
+ (i32.const 2)
+ )
+ )
+ )
+ (global.set $nn-tuple-global
+ ;; This tee will have to be fixed up for the new type.
+ (local.tee $y
+ (if (result (ref any) i32)
+ (i32.const 0)
+ ;; These gets will be invalid, so the local will have to be made nullable.
+ (local.get $x)
+ (local.get $x)
+ )
+ )
+ )
+ (local.get $y)
+ )
)
diff --git a/test/lit/passes/simplify-locals-gc-nn.wast b/test/lit/passes/simplify-locals-gc-nn.wast
index 170bc1553..2575ac807 100644
--- a/test/lit/passes/simplify-locals-gc-nn.wast
+++ b/test/lit/passes/simplify-locals-gc-nn.wast
@@ -49,6 +49,66 @@
)
)
+ ;; CHECK: (func $test-nn-tuple (type $0)
+ ;; CHECK-NEXT: (local $nn (i32 anyref i64))
+ ;; CHECK-NEXT: (nop)
+ ;; CHECK-NEXT: (try $try
+ ;; CHECK-NEXT: (do
+ ;; CHECK-NEXT: (local.set $nn
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (i64.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (catch_all
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (tuple.make
+ ;; CHECK-NEXT: (tuple.extract 0
+ ;; CHECK-NEXT: (local.get $nn)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (ref.as_non_null
+ ;; CHECK-NEXT: (tuple.extract 1
+ ;; CHECK-NEXT: (local.get $nn)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (tuple.extract 2
+ ;; CHECK-NEXT: (local.get $nn)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $test-nn-tuple
+ ;; Same as above, but now the local is a tuple containing a non-nullable element
+ (local $nn (i32 (ref any) i64))
+ (local.set $nn
+ (tuple.make
+ (i32.const 0)
+ (ref.as_non_null
+ (ref.null any)
+ )
+ (i64.const 0)
+ )
+ )
+ (try
+ (do
+ (drop
+ (local.get $nn)
+ )
+ )
+ (catch_all
+ (drop
+ (local.get $nn)
+ )
+ )
+ )
+ )
+
;; CHECK: (func $test-nullable (type $0)
;; CHECK-NEXT: (local $nullable anyref)
;; CHECK-NEXT: (nop)