diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/lit/passes/coalesce-locals-gc.wast | 141 | ||||
-rw-r--r-- | test/lit/passes/simplify-locals-gc-nn.wast | 60 | ||||
-rw-r--r-- | test/lit/validation/bad-non-nullable-locals.wast | 11 |
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) + ) + ) +) |