summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lit/passes/coalesce-locals-gc.wast141
-rw-r--r--test/lit/passes/simplify-locals-gc-nn.wast60
-rw-r--r--test/lit/validation/bad-non-nullable-locals.wast11
3 files changed, 200 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)
diff --git a/test/lit/validation/bad-non-nullable-locals.wast b/test/lit/validation/bad-non-nullable-locals.wast
index f22771591..9268e9b3a 100644
--- a/test/lit/validation/bad-non-nullable-locals.wast
+++ b/test/lit/validation/bad-non-nullable-locals.wast
@@ -59,3 +59,14 @@
(func $helper)
)
+;; CHECK: non-nullable local's sets must dominate gets
+(module
+ (func $tuple
+ ;; Since this tuple local has a non-nullable element, it is subject to the
+ ;; non-nullability rules.
+ (local $x (i32 (ref any) i64))
+ (drop
+ (local.get $x)
+ )
+ )
+)