summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r--src/passes/OptimizeInstructions.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 5d91ce29f..c9e1ced19 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -2029,14 +2029,33 @@ struct OptimizeInstructions
curr->type));
return;
} else if (result == GCTypeUtils::SuccessOnlyIfNull) {
- curr->type = Type(nullType, Nullable);
- // Call replaceCurrent() to make us re-optimize this node, as we may
- // have just unlocked further opportunities. (We could just continue
- // down to the rest, but we'd need to do more work to make sure all
- // the local state in this function is in sync which this change; it's
- // easier to just do another clean pass on this node.)
- replaceCurrent(curr);
- return;
+ // If either cast or ref types were non-nullable then the cast could
+ // never succeed, and we'd have reached |Failure|, above.
+ assert(curr->type.isNullable() && curr->ref->type.isNullable());
+
+ // The cast either returns null, or traps. In trapsNeverHappen mode
+ // we know the result, since it by assumption will not trap.
+ if (getPassOptions().trapsNeverHappen) {
+ replaceCurrent(builder.makeBlock(
+ {builder.makeDrop(curr->ref), builder.makeRefNull(nullType)},
+ curr->type));
+ return;
+ }
+
+ // Without trapsNeverHappen we can at least sharpen the type here, if
+ // it is not already a null type.
+ auto newType = Type(nullType, Nullable);
+ if (curr->type != newType) {
+ curr->type = newType;
+ // Call replaceCurrent() to make us re-optimize this node, as we
+ // may have just unlocked further opportunities. (We could just
+ // continue down to the rest, but we'd need to do more work to
+ // make sure all the local state in this function is in sync
+ // which this change; it's easier to just do another clean pass
+ // on this node.)
+ replaceCurrent(curr);
+ return;
+ }
}
auto** last = refp;