summaryrefslogtreecommitdiff
path: root/src/passes
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes')
-rw-r--r--src/passes/GUFA.cpp6
-rw-r--r--src/passes/OptimizeInstructions.cpp19
-rw-r--r--src/passes/Print.cpp5
3 files changed, 20 insertions, 10 deletions
diff --git a/src/passes/GUFA.cpp b/src/passes/GUFA.cpp
index 4250c76e9..137ffda17 100644
--- a/src/passes/GUFA.cpp
+++ b/src/passes/GUFA.cpp
@@ -237,10 +237,8 @@ struct GUFAOptimizer
if (refType.isRef()) {
// We have some knowledge of the type here. Use that to optimize: RefTest
// returns 1 if the input is of a subtype of the intended type, that is,
- // we are looking for a type in that cone of types. (Note that we use a
- // non-nullable cone since only a non-null can pass the test.)
- auto intendedContents =
- PossibleContents::fullConeType(Type(curr->intendedType, NonNullable));
+ // we are looking for a type in that cone of types.
+ auto intendedContents = PossibleContents::fullConeType(curr->castType);
auto optimize = [&](int32_t result) {
auto* last = Builder(*getModule()).makeConst(Literal(int32_t(result)));
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index ec714c1e1..097e0299a 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -2037,20 +2037,29 @@ struct OptimizeInstructions
Builder builder(*getModule());
+ if (curr->ref->type.isNull()) {
+ // The input is null, so we know whether this will succeed or fail.
+ int32_t result = curr->castType.isNullable() ? 1 : 0;
+ replaceCurrent(builder.makeBlock(
+ {builder.makeDrop(curr->ref), builder.makeConst(int32_t(result))}));
+ return;
+ }
+
auto refType = curr->ref->type.getHeapType();
- auto intendedType = curr->intendedType;
+ auto intendedType = curr->castType.getHeapType();
// See above in RefCast.
- if (!canBeCastTo(refType, intendedType)) {
+ if (!canBeCastTo(refType, intendedType) &&
+ (curr->castType.isNonNullable() || curr->ref->type.isNonNullable())) {
// This test cannot succeed, and will definitely return 0.
replaceCurrent(builder.makeSequence(builder.makeDrop(curr->ref),
builder.makeConst(int32_t(0))));
return;
}
- if (curr->ref->type.isNonNullable() &&
- HeapType::isSubType(refType, intendedType)) {
- // This static test will definitely succeed.
+ if (HeapType::isSubType(refType, intendedType) &&
+ (curr->castType.isNullable() || curr->ref->type.isNonNullable())) {
+ // This test will definitely succeed and return 1.
replaceCurrent(builder.makeBlock(
{builder.makeDrop(curr->ref), builder.makeConst(int32_t(1))}));
return;
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 2cd021b6f..d2fbf24d8 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -2110,7 +2110,10 @@ struct PrintExpressionContents
}
void visitRefTest(RefTest* curr) {
printMedium(o, "ref.test ");
- printHeapType(o, curr->intendedType, wasm);
+ if (curr->castType.isNullable()) {
+ printMedium(o, "null ");
+ }
+ printHeapType(o, curr->castType.getHeapType(), wasm);
}
void visitRefCast(RefCast* curr) {
if (printUnreachableReplacement(curr)) {