diff options
Diffstat (limited to 'test/lit/passes')
-rw-r--r-- | test/lit/passes/cfp.wast | 18 | ||||
-rw-r--r-- | test/lit/passes/coalesce-locals-gc.wast | 56 | ||||
-rw-r--r-- | test/lit/passes/issue-7087.wast | 31 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc-tnh.wast | 10 | ||||
-rw-r--r-- | test/lit/passes/remove-unused-brs_all-features.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/ssa.wast | 16 |
6 files changed, 100 insertions, 33 deletions
diff --git a/test/lit/passes/cfp.wast b/test/lit/passes/cfp.wast index 461baa373..e70cfc639 100644 --- a/test/lit/passes/cfp.wast +++ b/test/lit/passes/cfp.wast @@ -2332,9 +2332,11 @@ ;; CHECK-NEXT: (struct.set $A 0 ;; CHECK-NEXT: (select (result (ref null $A)) ;; CHECK-NEXT: (ref.null none) - ;; CHECK-NEXT: (local.tee $B - ;; CHECK-NEXT: (struct.new $B - ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: (block (result (ref null $A)) + ;; CHECK-NEXT: (local.tee $B + ;; CHECK-NEXT: (struct.new $B + ;; CHECK-NEXT: (i32.const 20) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) @@ -2361,10 +2363,12 @@ ;; This select is used to keep the type that reaches the struct.set $A, ;; and not $B, so it looks like a perfect copy of $A->$A. (select (result (ref null $A)) - (ref.null $A) - (local.tee $B - (struct.new $B - (i32.const 20) + (ref.null none) + (block (result (ref null $A)) + (local.tee $B + (struct.new $B + (i32.const 20) + ) ) ) (i32.const 0) diff --git a/test/lit/passes/coalesce-locals-gc.wast b/test/lit/passes/coalesce-locals-gc.wast index d2b6fcaeb..59232d1b4 100644 --- a/test/lit/passes/coalesce-locals-gc.wast +++ b/test/lit/passes/coalesce-locals-gc.wast @@ -25,7 +25,7 @@ (global $nn-tuple-global (mut (tuple (ref any) i32)) (tuple.make 2 (ref.i31 (i32.const 0)) (i32.const 1))) - ;; CHECK: (func $test-dead-get-non-nullable (type $6) (param $0 (ref struct)) + ;; CHECK: (func $test-dead-get-non-nullable (type $7) (param $0 (ref struct)) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result (ref struct)) @@ -43,7 +43,7 @@ ) ) - ;; CHECK: (func $br_on_null (type $7) (param $0 (ref null $array)) (result (ref null $array)) + ;; CHECK: (func $br_on_null (type $8) (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 @@ -79,7 +79,7 @@ ) ) - ;; CHECK: (func $nn-dead (type $4) + ;; CHECK: (func $nn-dead (type $3) ;; CHECK-NEXT: (local $0 funcref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.func $nn-dead) @@ -118,7 +118,7 @@ ) ) - ;; CHECK: (func $nn-dead-nameless (type $4) + ;; CHECK: (func $nn-dead-nameless (type $3) ;; CHECK-NEXT: (local $0 (ref func)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.func $nn-dead) @@ -149,26 +149,24 @@ ) ) - ;; CHECK: (func $unreachable-get-null (type $4) + ;; CHECK: (func $unreachable-get-null (type $3) ;; CHECK-NEXT: (local $0 anyref) ;; CHECK-NEXT: (local $1 i31ref) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result anyref) - ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (block (result i31ref) - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) (func $unreachable-get-null - ;; Check that we don't replace the local.get $null with a ref.null, which - ;; would have a more precise type. + ;; Check that we don't replace the local.get $null with just a ref.null, which + ;; would have a more precise type. We wrap the ref.null in a block instead. (local $null-any anyref) (local $null-i31 i31ref) (unreachable) @@ -180,6 +178,32 @@ ) ) + ;; CHECK: (func $unreachable-get-tuple (type $3) + ;; CHECK-NEXT: (local $0 (tuple anyref i32)) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (tuple.extract 2 0 + ;; CHECK-NEXT: (block (type $6) (result anyref i32) + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (ref.null none) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $unreachable-get-tuple + (local $tuple (tuple anyref i32)) + (unreachable) + (drop + ;; If we replaced the get with something with a more refined type, this + ;; extract would end up with a stale type. + (tuple.extract 2 0 + (local.get $tuple) + ) + ) + ) + ;; CHECK: (func $remove-tee-refinalize (type $5) (param $0 (ref null $A)) (param $1 (ref null $B)) (result structref) ;; CHECK-NEXT: (struct.get $B 0 ;; CHECK-NEXT: (local.get $1) @@ -218,16 +242,14 @@ ) ) - ;; CHECK: (func $replace-i31-local (type $8) (result i32) + ;; CHECK: (func $replace-i31-local (type $9) (result i32) ;; CHECK-NEXT: (local $0 i31ref) ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: (ref.test (ref i31) ;; CHECK-NEXT: (ref.cast i31ref ;; CHECK-NEXT: (block (result i31ref) - ;; CHECK-NEXT: (ref.i31 - ;; CHECK-NEXT: (i32.const 0) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (ref.null none) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -250,7 +272,7 @@ ) ) - ;; CHECK: (func $replace-struct-param (type $9) (param $0 f64) (param $1 (ref null $A)) (result f32) + ;; CHECK: (func $replace-struct-param (type $10) (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,7 +300,7 @@ ) ) - ;; CHECK: (func $test (type $10) (param $0 (ref any)) (result (ref any) i32) + ;; CHECK: (func $test (type $11) (param $0 (ref any)) (result (ref any) i32) ;; CHECK-NEXT: (local $1 (tuple anyref i32)) ;; CHECK-NEXT: (tuple.drop 2 ;; CHECK-NEXT: (tuple.make 2 diff --git a/test/lit/passes/issue-7087.wast b/test/lit/passes/issue-7087.wast new file mode 100644 index 000000000..096c88e5d --- /dev/null +++ b/test/lit/passes/issue-7087.wast @@ -0,0 +1,31 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; Regression test for a bug in TypeSSA. TypeSSA creates a new subtype, $t_1, +;; for use in the struct.new in the global initializer, but ran ReFinalize only +;; on function code, not on module-level code. As a result, the tuple.make +;; result type still used $t instead of $t_1 after TypeSSA. This stale type +;; caused Unsubtyping to incorrectly break the subtype relationship between $t +;; and $t_1, leading to a validation error. The fix was to refinalize +;; module-level code in TypeSSA and fix the validator so it would have caught +;; the stale type. + +;; RUN: wasm-opt %s -all --type-ssa --unsubtyping -S -o - | filecheck %s + +(module + ;; CHECK: (rec + ;; CHECK-NEXT: (type $t (sub (struct))) + (type $t (sub (struct))) + + ;; CHECK: (type $t_1 (sub $t (struct))) + + ;; CHECK: (global $g (tuple i32 (ref null $t)) (tuple.make 2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (struct.new_default $t_1) + ;; CHECK-NEXT: )) + (global $g (tuple i32 (ref null $t)) + (tuple.make 2 + (i32.const 0) + (struct.new $t) + ) + ) +) diff --git a/test/lit/passes/optimize-instructions-gc-tnh.wast b/test/lit/passes/optimize-instructions-gc-tnh.wast index ff2975766..c930f2fc1 100644 --- a/test/lit/passes/optimize-instructions-gc-tnh.wast +++ b/test/lit/passes/optimize-instructions-gc-tnh.wast @@ -497,7 +497,7 @@ ) ;; TNH: (func $null.arm.null.effects (type $void) - ;; TNH-NEXT: (block ;; (replaces unreachable StructSet we can't emit) + ;; TNH-NEXT: (block ;; TNH-NEXT: (drop ;; TNH-NEXT: (select ;; TNH-NEXT: (unreachable) @@ -505,9 +505,6 @@ ;; TNH-NEXT: (call $get-i32) ;; TNH-NEXT: ) ;; TNH-NEXT: ) - ;; TNH-NEXT: (drop - ;; TNH-NEXT: (i32.const 1) - ;; TNH-NEXT: ) ;; TNH-NEXT: (unreachable) ;; TNH-NEXT: ) ;; TNH-NEXT: (block @@ -523,7 +520,7 @@ ;; TNH-NEXT: ) ;; TNH-NEXT: ) ;; NO_TNH: (func $null.arm.null.effects (type $void) - ;; NO_TNH-NEXT: (block ;; (replaces unreachable StructSet we can't emit) + ;; NO_TNH-NEXT: (block ;; NO_TNH-NEXT: (drop ;; NO_TNH-NEXT: (select ;; NO_TNH-NEXT: (unreachable) @@ -531,9 +528,6 @@ ;; NO_TNH-NEXT: (call $get-i32) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: ) - ;; NO_TNH-NEXT: (drop - ;; NO_TNH-NEXT: (i32.const 1) - ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (unreachable) ;; NO_TNH-NEXT: ) ;; NO_TNH-NEXT: (block diff --git a/test/lit/passes/remove-unused-brs_all-features.wast b/test/lit/passes/remove-unused-brs_all-features.wast index 4e722a043..e2d89a5ea 100644 --- a/test/lit/passes/remove-unused-brs_all-features.wast +++ b/test/lit/passes/remove-unused-brs_all-features.wast @@ -119,7 +119,7 @@ (func $i32_=>_none (param i32) ) ;; CHECK: (func $selectify (type $6) (param $x i32) (result funcref) - ;; CHECK-NEXT: (select (result funcref) + ;; CHECK-NEXT: (select (result (ref func)) ;; CHECK-NEXT: (ref.func $none_=>_i32) ;; CHECK-NEXT: (ref.func $i32_=>_none) ;; CHECK-NEXT: (local.get $x) diff --git a/test/lit/passes/ssa.wast b/test/lit/passes/ssa.wast index b082cd888..0d696f75a 100644 --- a/test/lit/passes/ssa.wast +++ b/test/lit/passes/ssa.wast @@ -58,4 +58,20 @@ (unreachable) ) ) + + ;; CHECK: (func $null-tuple (type $4) (result funcref) + ;; CHECK-NEXT: (local $tuple (tuple i32 funcref)) + ;; CHECK-NEXT: (tuple.extract 2 1 + ;; CHECK-NEXT: (tuple.make 2 + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (ref.null nofunc) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $null-tuple (result funcref) + (local $tuple (tuple i32 funcref)) + (tuple.extract 2 1 + (local.get $tuple) + ) + ) ) |