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.cpp37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 4ffd6be67..059ef28fb 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -1267,6 +1267,10 @@ struct OptimizeInstructions
}
void visitCallRef(CallRef* curr) {
+ skipNonNullCast(curr->target);
+ if (trapOnNull(curr, curr->target)) {
+ return;
+ }
if (curr->target->type == Type::unreachable) {
// The call_ref is not reached; leave this for DCE.
return;
@@ -1509,6 +1513,17 @@ struct OptimizeInstructions
return getDroppedChildrenAndAppend(curr, result);
}
+ bool trapOnNull(Expression* curr, Expression* ref) {
+ if (ref->type.isNull()) {
+ replaceCurrent(getDroppedChildrenAndAppend(
+ curr, Builder(*getModule()).makeUnreachable()));
+ // Propagate the unreachability.
+ refinalize = true;
+ return true;
+ }
+ return false;
+ }
+
void visitRefEq(RefEq* curr) {
// The types may prove that the same reference cannot appear on both sides.
auto leftType = curr->left->type;
@@ -1564,10 +1579,16 @@ struct OptimizeInstructions
}
}
- void visitStructGet(StructGet* curr) { skipNonNullCast(curr->ref); }
+ void visitStructGet(StructGet* curr) {
+ skipNonNullCast(curr->ref);
+ trapOnNull(curr, curr->ref);
+ }
void visitStructSet(StructSet* curr) {
skipNonNullCast(curr->ref);
+ if (trapOnNull(curr, curr->ref)) {
+ return;
+ }
if (curr->ref->type != Type::unreachable && curr->value->type.isInteger()) {
const auto& fields = curr->ref->type.getHeapType().getStruct().fields;
@@ -1715,10 +1736,16 @@ struct OptimizeInstructions
return true;
}
- void visitArrayGet(ArrayGet* curr) { skipNonNullCast(curr->ref); }
+ void visitArrayGet(ArrayGet* curr) {
+ skipNonNullCast(curr->ref);
+ trapOnNull(curr, curr->ref);
+ }
void visitArraySet(ArraySet* curr) {
skipNonNullCast(curr->ref);
+ if (trapOnNull(curr, curr->ref)) {
+ return;
+ }
if (curr->ref->type != Type::unreachable && curr->value->type.isInteger()) {
auto element = curr->ref->type.getHeapType().getArray().element;
@@ -1726,11 +1753,15 @@ struct OptimizeInstructions
}
}
- void visitArrayLen(ArrayLen* curr) { skipNonNullCast(curr->ref); }
+ void visitArrayLen(ArrayLen* curr) {
+ skipNonNullCast(curr->ref);
+ trapOnNull(curr, curr->ref);
+ }
void visitArrayCopy(ArrayCopy* curr) {
skipNonNullCast(curr->destRef);
skipNonNullCast(curr->srcRef);
+ trapOnNull(curr, curr->destRef) || trapOnNull(curr, curr->srcRef);
}
bool canBeCastTo(HeapType a, HeapType b) {