summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wasm.cpp27
-rw-r--r--test/lit/passes/optimize-casts.wast8
-rw-r--r--test/lit/passes/optimize-instructions-call_ref.wast2
-rw-r--r--test/lit/passes/optimize-instructions-gc-iit.wast4
-rw-r--r--test/lit/passes/optimize-instructions-gc.wast16
-rw-r--r--test/lit/passes/precompute-gc.wast2
-rw-r--r--test/lit/passes/signature-refining.wast2
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: )