summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp15
-rw-r--r--test/lit/passes/optimize-instructions-gc.wast4
2 files changed, 17 insertions, 2 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 6b2a5a1cd..c2142fe6c 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1595,6 +1595,21 @@ struct OptimizeInstructions
}
}
+ // A nullable cast can be turned into a non-nullable one:
+ //
+ // (struct.get ;; or something else that traps on a null ref
+ // (ref.cast null
+ // =>
+ // (struct.get
+ // (ref.cast ;; now non-nullable
+ //
+ // Either way we trap here, but refining the type may have benefits later.
+ if (ref->type.isNullable()) {
+ if (auto* cast = ref->dynCast<RefCast>()) {
+ cast->type = Type(cast->type.getHeapType(), NonNullable);
+ }
+ }
+
auto fallthrough =
Properties::getFallthrough(ref, getPassOptions(), *getModule());
diff --git a/test/lit/passes/optimize-instructions-gc.wast b/test/lit/passes/optimize-instructions-gc.wast
index 592ec80cd..9ca0c81e0 100644
--- a/test/lit/passes/optimize-instructions-gc.wast
+++ b/test/lit/passes/optimize-instructions-gc.wast
@@ -993,7 +993,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (struct.get_u $struct $i8
- ;; CHECK-NEXT: (ref.cast null $struct
+ ;; CHECK-NEXT: (ref.cast $struct
;; CHECK-NEXT: (local.get $x)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
@@ -1016,7 +1016,7 @@
;; NOMNL-NEXT: )
;; NOMNL-NEXT: (drop
;; NOMNL-NEXT: (struct.get_u $struct $i8
- ;; NOMNL-NEXT: (ref.cast null $struct
+ ;; NOMNL-NEXT: (ref.cast $struct
;; NOMNL-NEXT: (local.get $x)
;; NOMNL-NEXT: )
;; NOMNL-NEXT: )