diff options
-rw-r--r-- | src/wasm/wasm.cpp | 27 | ||||
-rw-r--r-- | test/lit/passes/optimize-casts.wast | 8 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-call_ref.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc-iit.wast | 4 | ||||
-rw-r--r-- | test/lit/passes/optimize-instructions-gc.wast | 16 | ||||
-rw-r--r-- | test/lit/passes/precompute-gc.wast | 2 | ||||
-rw-r--r-- | test/lit/passes/signature-refining.wast | 2 |
7 files changed, 30 insertions, 31 deletions
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 648a25d9e..74b944bb6 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -948,23 +948,18 @@ void RefCast::finalize() { return; } - // Do not unnecessarily lose non-nullability info. We could leave this for - // optimizations, but doing it here as part of finalization/refinalization - // ensures that type information flows through in an optimal manner and can be - // used as soon as possible. - if (ref->type.isNonNullable() && type.isNullable()) { - type = Type(type.getHeapType(), NonNullable); - } - - // Do not unnecessarily lose heap type info, as above for nullability. Note - // that we must check if the ref has a heap type, as we reach this before - // validation, which will error if the ref does not in fact have a heap type. - // (This is a downside of propagating type information here, as opposed to - // leaving it for an optimization pass.) - if (ref->type.isRef() && - HeapType::isSubType(ref->type.getHeapType(), type.getHeapType())) { - type = Type(ref->type.getHeapType(), type.getNullability()); + // We reach this before validation, so the input type might be totally wrong. + // Return early in this case to avoid doing the wrong thing below. + if (!ref->type.isRef()) { + return; } + + // Do not unnecessarily lose type information. We could leave this for + // optimizations (and indeed we do a more powerful version of this in + // OptimizeInstructions), but doing it here as part of + // finalization/refinalization ensures that type information flows through in + // an optimal manner and can be used as soon as possible. + type = Type::getGreatestLowerBound(type, ref->type); } void BrOn::finalize() { diff --git a/test/lit/passes/optimize-casts.wast b/test/lit/passes/optimize-casts.wast index 254daedc4..097f03c62 100644 --- a/test/lit/passes/optimize-casts.wast +++ b/test/lit/passes/optimize-casts.wast @@ -824,7 +824,9 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast $D - ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: (block (result anyref) + ;; CHECK-NEXT: (local.get $x) + ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) @@ -841,7 +843,9 @@ ) (drop (ref.cast $D - (local.get $x) + (block (result anyref) + (local.get $x) + ) ) ) ) diff --git a/test/lit/passes/optimize-instructions-call_ref.wast b/test/lit/passes/optimize-instructions-call_ref.wast index a085e1ed4..3b2ec2b54 100644 --- a/test/lit/passes/optimize-instructions-call_ref.wast +++ b/test/lit/passes/optimize-instructions-call_ref.wast @@ -160,7 +160,7 @@ ;; CHECK: (func $fallthrough-bad-type (type $none_=>_i32) (result i32) ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref nofunc)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.func $return-nothing) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/optimize-instructions-gc-iit.wast b/test/lit/passes/optimize-instructions-gc-iit.wast index b3d5a2559..e4694f4c7 100644 --- a/test/lit/passes/optimize-instructions-gc-iit.wast +++ b/test/lit/passes/optimize-instructions-gc-iit.wast @@ -39,7 +39,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $child) ;; CHECK-NEXT: ) @@ -60,7 +60,7 @@ ;; TNH-NEXT: ) ;; TNH-NEXT: ) ;; TNH-NEXT: (drop - ;; TNH-NEXT: (block + ;; TNH-NEXT: (block (result (ref none)) ;; TNH-NEXT: (drop ;; TNH-NEXT: (local.get $child) ;; TNH-NEXT: ) diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast index 6d9e32d3d..e7933e8a1 100644 --- a/test/lit/passes/optimize-instructions-gc.wast +++ b/test/lit/passes/optimize-instructions-gc.wast @@ -584,7 +584,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast i31 ;; CHECK-NEXT: (local.get $x) @@ -1088,7 +1088,7 @@ ;; CHECK: (func $incompatible-cast-of-non-null (type $ref|$struct|_=>_none) (param $struct (ref $struct)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $struct) ;; CHECK-NEXT: ) @@ -1988,7 +1988,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast $array ;; CHECK-NEXT: (local.get $x) @@ -1998,7 +1998,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast $array ;; CHECK-NEXT: (local.get $x) @@ -2008,7 +2008,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (ref.cast $array ;; CHECK-NEXT: (local.get $x) @@ -2320,7 +2320,7 @@ ;; CHECK: (func $ref-cast-heap-type-incompatible (type $ref?|$B|_ref|$B|_=>_none) (param $null-b (ref null $B)) (param $b (ref $B)) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $b) ;; CHECK-NEXT: ) @@ -2328,7 +2328,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $null-b) ;; CHECK-NEXT: ) @@ -2336,7 +2336,7 @@ ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block (result (ref none)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $b) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/precompute-gc.wast b/test/lit/passes/precompute-gc.wast index 369bd685c..94b076687 100644 --- a/test/lit/passes/precompute-gc.wast +++ b/test/lit/passes/precompute-gc.wast @@ -810,7 +810,7 @@ ;; CHECK: (func $odd-cast-and-get-non-null (type $ref|$func-return-i32|_=>_none) (param $temp (ref $func-return-i32)) ;; CHECK-NEXT: (local.set $temp - ;; CHECK-NEXT: (ref.cast $func-return-i32 + ;; CHECK-NEXT: (ref.cast nofunc ;; CHECK-NEXT: (ref.func $receive-f64) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast index 1b575174d..dc674b1b0 100644 --- a/test/lit/passes/signature-refining.wast +++ b/test/lit/passes/signature-refining.wast @@ -873,7 +873,7 @@ ;; CHECK: (func $1 (type $ref|$[i8]|_=>_none) (param $2 (ref $[i8])) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (ref.cast struct + ;; CHECK-NEXT: (ref.cast none ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) |