summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/passes/OptimizeInstructions.cpp9
-rw-r--r--test/lit/passes/optimize-instructions-gc-tnh.wast48
2 files changed, 41 insertions, 16 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 6d4b7b674..bbb497f39 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1495,20 +1495,21 @@ struct OptimizeInstructions
// |requiredType| is not provided we will accept any type there.
//
// See "notes on removing casts", above, for when this is safe to do.
- void skipCast(Expression*& input,
- Type requiredType = Type(HeapType::any, Nullable)) {
+ void skipCast(Expression*& input, Type requiredType = Type::none) {
// Traps-never-happen mode is a requirement for us to optimize here.
if (!getPassOptions().trapsNeverHappen) {
return;
}
while (1) {
if (auto* as = input->dynCast<RefAs>()) {
- if (Type::isSubType(as->value->type, requiredType)) {
+ if (requiredType == Type::none ||
+ Type::isSubType(as->value->type, requiredType)) {
input = as->value;
continue;
}
} else if (auto* cast = input->dynCast<RefCast>()) {
- if (Type::isSubType(cast->ref->type, requiredType)) {
+ if (requiredType == Type::none ||
+ Type::isSubType(cast->ref->type, requiredType)) {
input = cast->ref;
continue;
}
diff --git a/test/lit/passes/optimize-instructions-gc-tnh.wast b/test/lit/passes/optimize-instructions-gc-tnh.wast
index 2e9479ff5..c6aab6c88 100644
--- a/test/lit/passes/optimize-instructions-gc-tnh.wast
+++ b/test/lit/passes/optimize-instructions-gc-tnh.wast
@@ -7,6 +7,10 @@
;; NO_TNH: (type $struct (struct (field (mut i32))))
(type $struct (struct_subtype (field (mut i32)) data))
+ ;; TNH: (type $void (func))
+ ;; NO_TNH: (type $void (func))
+ (type $void (func))
+
;; TNH: (func $ref.eq (type $eqref_eqref_=>_i32) (param $a eqref) (param $b eqref) (result i32)
;; TNH-NEXT: (ref.eq
;; TNH-NEXT: (local.get $a)
@@ -113,25 +117,45 @@
)
)
- ;; TNH: (func $ref.is_b (type $eqref_=>_i32) (param $a eqref) (result i32)
+ ;; TNH: (func $ref.is_b (type $eqref_funcref_=>_i32) (param $a eqref) (param $f funcref) (result i32)
+ ;; TNH-NEXT: (drop
+ ;; TNH-NEXT: (ref.is_null
+ ;; TNH-NEXT: (local.get $a)
+ ;; TNH-NEXT: )
+ ;; TNH-NEXT: )
;; TNH-NEXT: (ref.is_null
- ;; TNH-NEXT: (local.get $a)
+ ;; TNH-NEXT: (local.get $f)
;; TNH-NEXT: )
;; TNH-NEXT: )
- ;; NO_TNH: (func $ref.is_b (type $eqref_=>_i32) (param $a eqref) (result i32)
+ ;; NO_TNH: (func $ref.is_b (type $eqref_funcref_=>_i32) (param $a eqref) (param $f funcref) (result i32)
+ ;; NO_TNH-NEXT: (drop
+ ;; NO_TNH-NEXT: (ref.is_null
+ ;; NO_TNH-NEXT: (ref.cast null $struct
+ ;; NO_TNH-NEXT: (local.get $a)
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: )
+ ;; NO_TNH-NEXT: )
;; NO_TNH-NEXT: (ref.is_null
- ;; NO_TNH-NEXT: (ref.cast null $struct
- ;; NO_TNH-NEXT: (local.get $a)
+ ;; NO_TNH-NEXT: (ref.cast null $void
+ ;; NO_TNH-NEXT: (local.get $f)
;; NO_TNH-NEXT: )
;; NO_TNH-NEXT: )
;; NO_TNH-NEXT: )
- (func $ref.is_b(param $a (ref null eq)) (result i32)
+ (func $ref.is_b (param $a eqref) (param $f funcref) (result i32)
;; Here we only have a cast, and no ref.as operations that force the value
;; to be non-nullable. That means we cannot remove the ref.is, but we can
;; remove the cast in TNH.
+ (drop
+ (ref.is_null
+ (ref.cast null $struct
+ (local.get $a)
+ )
+ )
+ )
+ ;; It works on func references, too.
(ref.is_null
- (ref.cast null $struct
- (local.get $a)
+ (ref.cast null $void
+ (local.get $f)
)
)
)
@@ -290,7 +314,7 @@
)
)
- ;; TNH: (func $select.arm.null.effects (type $none_=>_none)
+ ;; TNH: (func $select.arm.null.effects (type $void)
;; TNH-NEXT: (local $0 (ref $struct))
;; TNH-NEXT: (local $1 (ref $struct))
;; TNH-NEXT: (struct.set $struct 0
@@ -328,7 +352,7 @@
;; TNH-NEXT: (i32.const 2)
;; TNH-NEXT: )
;; TNH-NEXT: )
- ;; NO_TNH: (func $select.arm.null.effects (type $none_=>_none)
+ ;; NO_TNH: (func $select.arm.null.effects (type $void)
;; NO_TNH-NEXT: (struct.set $struct 0
;; NO_TNH-NEXT: (select (result (ref null $struct))
;; NO_TNH-NEXT: (call $get-ref)
@@ -367,7 +391,7 @@
)
)
- ;; TNH: (func $null.arm.null.effects (type $none_=>_none)
+ ;; TNH: (func $null.arm.null.effects (type $void)
;; TNH-NEXT: (block ;; (replaces something unreachable we can't emit)
;; TNH-NEXT: (drop
;; TNH-NEXT: (block (result nullref)
@@ -390,7 +414,7 @@
;; TNH-NEXT: (unreachable)
;; TNH-NEXT: )
;; TNH-NEXT: )
- ;; NO_TNH: (func $null.arm.null.effects (type $none_=>_none)
+ ;; NO_TNH: (func $null.arm.null.effects (type $void)
;; NO_TNH-NEXT: (struct.set $struct 0
;; NO_TNH-NEXT: (select (result (ref null $struct))
;; NO_TNH-NEXT: (ref.as_non_null