diff options
Diffstat (limited to 'test/lit/passes/optimize-instructions-gc.wast')
-rw-r--r-- | test/lit/passes/optimize-instructions-gc.wast | 293 |
1 files changed, 78 insertions, 215 deletions
diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index f53237f02..f6a1b5d09 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -18,24 +18,26 @@ ;; NOMNL: (type $A (struct_subtype (field i32) data)) (type $A (struct (field i32))) + ;; CHECK: (type $B (struct (field i32) (field i32) (field f32))) + ;; CHECK: (type $array (array (mut i8))) + ;; NOMNL: (type $B (struct_subtype (field i32) (field i32) (field f32) $A)) + ;; NOMNL: (type $array (array_subtype (mut i8) data)) (type $array (array (mut i8))) - ;; CHECK: (type $B (struct (field i32) (field i32) (field f32))) - ;; 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 (field i32) (field i32) (field f32) (field i64))) ;; NOMNL: (type $B-child (struct_subtype (field i32) (field i32) (field f32) (field i64) $B)) (type $B-child (struct_subtype (field i32) (field i32) (field f32) (field i64) $B)) - ;; CHECK: (type $empty (struct )) + ;; NOMNL: (type $C (struct_subtype (field i32) (field i32) (field f64) $A)) + ;; NOMNL: (type $empty (struct_subtype data)) (type $empty (struct)) ;; CHECK: (type $C (struct (field i32) (field i32) (field f64))) - ;; NOMNL: (type $C (struct_subtype (field i32) (field i32) (field f64) $A)) (type $C (struct_subtype (field i32) (field i32) (field f64) $A)) ;; CHECK: (import "env" "get-i32" (func $get-i32 (result i32))) @@ -966,12 +968,8 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.eq - ;; CHECK-NEXT: (struct.new_default_with_rtt $struct - ;; CHECK-NEXT: (rtt.canon $struct) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (struct.new_default_with_rtt $struct - ;; CHECK-NEXT: (rtt.canon $struct) - ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (struct.new_default $struct) + ;; CHECK-NEXT: (struct.new_default $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -1003,12 +1001,8 @@ ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (ref.eq - ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct - ;; NOMNL-NEXT: (rtt.canon $struct) - ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (struct.new_default_with_rtt $struct - ;; NOMNL-NEXT: (rtt.canon $struct) - ;; NOMNL-NEXT: ) + ;; NOMNL-NEXT: (struct.new_default $struct) + ;; NOMNL-NEXT: (struct.new_default $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop @@ -1042,12 +1036,8 @@ ;; allocation prevents optimization (drop (ref.eq - (struct.new_default_with_rtt $struct - (rtt.canon $struct) - ) - (struct.new_default_with_rtt $struct - (rtt.canon $struct) - ) + (struct.new_default $struct) + (struct.new_default $struct) ) ) ;; but irrelevant allocations do not prevent optimization @@ -1056,17 +1046,13 @@ (block (result eqref) ;; an allocation that does not trouble us (drop - (struct.new_default_with_rtt $struct - (rtt.canon $struct) - ) + (struct.new_default $struct) ) (local.get $x) ) (block (result eqref) (drop - (struct.new_default_with_rtt $struct - (rtt.canon $struct) - ) + (struct.new_default $struct) ) ;; add a nop to make the two inputs to ref.eq not structurally equal, ;; but in a way that does not matter (since only the value falling @@ -1091,9 +1077,8 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -1102,9 +1087,8 @@ ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (ref.eq ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) @@ -1115,9 +1099,8 @@ (drop (ref.eq (local.get $x) - (ref.cast + (ref.cast_static $struct (local.get $x) - (rtt.canon $struct) ) ) ) @@ -1126,132 +1109,117 @@ ;; CHECK: (func $flip-cast-of-as-non-null (param $x anyref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.as_non_null - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (struct.get_u $struct $i8 - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (ref.as_func ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (ref.as_data ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (ref.as_i31 ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $flip-cast-of-as-non-null (type $anyref_=>_none) (param $x anyref) ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (ref.as_non_null - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (struct.get_u $struct $i8 - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (ref.as_func ;; NOMNL-NEXT: (local.get $x) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (ref.as_data ;; NOMNL-NEXT: (local.get $x) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (ref.as_i31 ;; NOMNL-NEXT: (local.get $x) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $flip-cast-of-as-non-null (param $x anyref) (drop - (ref.cast + (ref.cast_static $struct ;; this can be moved through the ref.cast outward. (ref.as_non_null (local.get $x) ) - (rtt.canon $struct) ) ) (drop ;; an example of how this helps: the struct.get will trap on null anyhow (struct.get_u $struct 0 - (ref.cast + (ref.cast_static $struct ;; this can be moved through the ref.cast outward. (ref.as_non_null (local.get $x) ) - (rtt.canon $struct) ) ) ) ;; other ref.as* operations are ignored for now (drop - (ref.cast + (ref.cast_static $struct (ref.as_func (local.get $x) ) - (rtt.canon $struct) ) ) (drop - (ref.cast + (ref.cast_static $struct (ref.as_data (local.get $x) ) - (rtt.canon $struct) ) ) (drop - (ref.cast + (ref.cast_static $struct (ref.as_i31 (local.get $x) ) - (rtt.canon $struct) ) ) ) @@ -1461,48 +1429,46 @@ ;; CHECK: (func $ref-cast-squared (param $x eqref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $ref-cast-squared (type $eqref_=>_none) (param $x eqref) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $ref-cast-squared (param $x eqref) ;; Identical ref.casts can be folded together. (drop - (ref.cast - (ref.cast + (ref.cast_static $struct + (ref.cast_static $struct (local.get $x) - (rtt.canon $struct) ) - (rtt.canon $struct) ) ) ) ;; CHECK: (func $ref-cast-squared-fallthrough (param $x eqref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (local.tee $x - ;; CHECK-NEXT: (ref.cast - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: (ref.cast_static $struct + ;; CHECK-NEXT: (local.tee $x + ;; CHECK-NEXT: (ref.cast_static $struct + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $ref-cast-squared-fallthrough (type $eqref_=>_none) (param $x eqref) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (local.tee $x - ;; NOMNL-NEXT: (ref.cast - ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (rtt.canon $struct) + ;; NOMNL-NEXT: (ref.cast_static $struct + ;; NOMNL-NEXT: (local.tee $x + ;; NOMNL-NEXT: (ref.cast_static $struct + ;; NOMNL-NEXT: (local.get $x) + ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) @@ -1510,128 +1476,68 @@ (func $ref-cast-squared-fallthrough (param $x eqref) ;; A fallthrough in the middle does not prevent this optimization. (drop - (ref.cast + (ref.cast_static $struct (local.tee $x - (ref.cast + (ref.cast_static $struct (local.get $x) - (rtt.canon $struct) ) ) - (rtt.canon $struct) ) ) ) ;; CHECK: (func $ref-cast-cubed (param $x eqref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $ref-cast-cubed (type $eqref_=>_none) (param $x eqref) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $ref-cast-cubed (param $x eqref) ;; Three and more also work. (drop - (ref.cast - (ref.cast - (ref.cast + (ref.cast_static $struct + (ref.cast_static $struct + (ref.cast_static $struct (local.get $x) - (rtt.canon $struct) ) - (rtt.canon $struct) ) - (rtt.canon $struct) ) ) ) ;; CHECK: (func $ref-cast-squared-different (param $x eqref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast - ;; CHECK-NEXT: (ref.cast - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (rtt.canon $empty) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (rtt.canon $struct) + ;; CHECK-NEXT: (ref.cast_static $struct + ;; CHECK-NEXT: (local.get $x) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $ref-cast-squared-different (type $eqref_=>_none) (param $x eqref) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct + ;; NOMNL-NEXT: (ref.cast_static $empty ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (rtt.canon $empty) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $ref-cast-squared-different (param $x eqref) ;; Different casts cannot be folded. (drop - (ref.cast - (ref.cast - (local.get $x) - (rtt.canon $empty) - ) - (rtt.canon $struct) - ) - ) - ) - ;; CHECK: (func $ref-cast-squared-effects (param $x eqref) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast - ;; CHECK-NEXT: (ref.cast - ;; CHECK-NEXT: (local.get $x) - ;; CHECK-NEXT: (call $get-rtt) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (call $get-rtt) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; CHECK-NEXT: ) - ;; NOMNL: (func $ref-cast-squared-effects (type $eqref_=>_none) (param $x eqref) - ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast - ;; NOMNL-NEXT: (ref.cast - ;; NOMNL-NEXT: (local.get $x) - ;; NOMNL-NEXT: (call $get-rtt) - ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (call $get-rtt) - ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: ) - (func $ref-cast-squared-effects (param $x eqref) - ;; The rtts are equal but have side effects, preventing optimization. - (drop - (ref.cast - (ref.cast + (ref.cast_static $struct + (ref.cast_static $empty (local.get $x) - (call $get-rtt) ) - (call $get-rtt) ) ) ) - ;; Helper function for above. - ;; CHECK: (func $get-rtt (result (rtt $empty)) - ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: ) - ;; NOMNL: (func $get-rtt (type $none_=>_rtt_$empty) (result (rtt $empty)) - ;; NOMNL-NEXT: (unreachable) - ;; NOMNL-NEXT: ) - (func $get-rtt (result (rtt $empty)) - (unreachable) - ) - ;; CHECK: (func $ref-eq-null (param $x eqref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.is_null @@ -2024,9 +1930,6 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (rtt.canon $array) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2037,18 +1940,14 @@ ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (local.get $struct) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (rtt.canon $array) - ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (unreachable) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $incompatible-cast-of-non-null (param $struct (ref $struct)) (drop - (ref.cast + (ref.cast_static $array (local.get $struct) - (rtt.canon $array) ) ) ) @@ -2059,9 +1958,6 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.null $struct) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (rtt.canon $array) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null $array) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2073,9 +1969,6 @@ ;; CHECK-NEXT: (ref.null $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (rtt.canon $array) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (ref.null $array) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2087,9 +1980,6 @@ ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (ref.null $struct) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (rtt.canon $array) - ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (ref.null $array) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) @@ -2101,9 +1991,6 @@ ;; NOMNL-NEXT: (ref.null $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (rtt.canon $array) - ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (ref.null $array) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) @@ -2111,45 +1998,40 @@ ;; NOMNL-NEXT: ) (func $incompatible-cast-of-null (drop - (ref.cast + (ref.cast_static $array (ref.null $struct) - (rtt.canon $array) ) ) (drop - (ref.cast + (ref.cast_static $array ;; The fallthrough is null, but the node's child's type is non-nullable, ;; so we must add a ref.as_non_null on the outside to keep the type ;; identical. (ref.as_non_null (ref.null $struct) ) - (rtt.canon $array) ) ) ) ;; CHECK: (func $incompatible-cast-of-unknown (param $struct (ref null $struct)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $array ;; CHECK-NEXT: (local.get $struct) - ;; CHECK-NEXT: (rtt.canon $array) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $incompatible-cast-of-unknown (type $ref?|$struct|_=>_none) (param $struct (ref null $struct)) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $array ;; NOMNL-NEXT: (local.get $struct) - ;; NOMNL-NEXT: (rtt.canon $array) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $incompatible-cast-of-unknown (param $struct (ref null $struct)) (drop - (ref.cast + (ref.cast_static $array (local.get $struct) - (rtt.canon $array) ) ) ) @@ -2160,9 +2042,6 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (rtt.canon $array) - ;; CHECK-NEXT: ) ;; CHECK-NEXT: (i32.const 0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -2173,9 +2052,6 @@ ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (local.get $struct) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (rtt.canon $array) - ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (i32.const 0) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) @@ -2183,70 +2059,61 @@ (func $incompatible-test (param $struct (ref null $struct)) (drop ;; This test will definitely fail, so we can turn it into 0. - (ref.test + (ref.test_static $array (local.get $struct) - (rtt.canon $array) ) ) ) ;; CHECK: (func $subtype-compatible (param $A (ref null $A)) (param $B (ref null $B)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.test + ;; CHECK-NEXT: (ref.test_static $B ;; CHECK-NEXT: (local.get $A) - ;; CHECK-NEXT: (rtt.canon $B) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.test + ;; CHECK-NEXT: (ref.test_static $A ;; CHECK-NEXT: (local.get $B) - ;; CHECK-NEXT: (rtt.canon $A) ;; 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 - ;; NOMNL-NEXT: (ref.test + ;; NOMNL-NEXT: (ref.test_static $B ;; NOMNL-NEXT: (local.get $A) - ;; NOMNL-NEXT: (rtt.canon $B) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.test + ;; NOMNL-NEXT: (ref.test_static $A ;; NOMNL-NEXT: (local.get $B) - ;; NOMNL-NEXT: (rtt.canon $A) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $subtype-compatible (param $A (ref null $A)) (param $B (ref null $B)) (drop ;; B is a subtype of A, so this can work. - (ref.test + (ref.test_static $B (local.get $A) - (rtt.canon $B) ) ) (drop ;; The other direction works too. - (ref.test + (ref.test_static $A (local.get $B) - (rtt.canon $A) ) ) ) ;; CHECK: (func $ref.test-unreachable (param $A (ref null $A)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.test + ;; CHECK-NEXT: (ref.test_static $A ;; CHECK-NEXT: (unreachable) - ;; CHECK-NEXT: (rtt.canon $A) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $ref.test-unreachable (type $ref?|$A|_=>_none) (param $A (ref null $A)) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.test + ;; NOMNL-NEXT: (ref.test_static $A ;; NOMNL-NEXT: (unreachable) - ;; NOMNL-NEXT: (rtt.canon $A) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) @@ -2254,42 +2121,39 @@ (drop ;; We should ignore unreachable ref.tests and not try to compare their ;; HeapTypes. - (ref.test + (ref.test_static $A (unreachable) - (rtt.canon $A) ) ) ) ;; CHECK: (func $consecutive-opts-with-unreachable (param $func funcref) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast + ;; CHECK-NEXT: (ref.cast_static $struct ;; CHECK-NEXT: (block (result dataref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $func) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (unreachable) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (rtt.canon $struct) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; NOMNL: (func $consecutive-opts-with-unreachable (type $funcref_=>_none) (param $func funcref) ;; NOMNL-NEXT: (drop - ;; NOMNL-NEXT: (ref.cast + ;; NOMNL-NEXT: (ref.cast_static $struct ;; NOMNL-NEXT: (block (result dataref) ;; NOMNL-NEXT: (drop ;; NOMNL-NEXT: (local.get $func) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: (unreachable) ;; NOMNL-NEXT: ) - ;; NOMNL-NEXT: (rtt.canon $struct) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) ;; NOMNL-NEXT: ) (func $consecutive-opts-with-unreachable (param $func funcref) (drop - (ref.cast + (ref.cast_static $struct ;; Casting a funcref to data will definitely fail, so this will be ;; replaced with an unreachable. But it should be enclosed in a block of ;; the previous type, so that the outside ref.cast is not confused. This @@ -2302,7 +2166,6 @@ (ref.as_data (local.get $func) ) - (rtt.canon $struct) ) ) ) |