diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/CoalesceLocals.cpp | 1 | ||||
-rw-r--r-- | src/passes/Precompute.cpp | 24 |
2 files changed, 21 insertions, 4 deletions
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp index ad64b066c..c58a48834 100644 --- a/src/passes/CoalesceLocals.cpp +++ b/src/passes/CoalesceLocals.cpp @@ -34,7 +34,6 @@ #include "pass.h" #include "support/learning.h" #include "support/permutations.h" -#include "wasm-builder.h" #include "wasm.h" #ifdef CFG_PROFILE #include "support/timing.h" diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp index c07286ec9..3e2e7a64f 100644 --- a/src/passes/Precompute.cpp +++ b/src/passes/Precompute.cpp @@ -311,9 +311,27 @@ private: // somehow know the entire expression precomputes to a 42, then we can // propagate that 42 along to the users, regardless of whatever the call // did globally.) - auto values = setValues[set] = - precomputeValue(Properties::getFallthrough( - set->value, getPassOptions(), getModule()->features)); + auto values = precomputeValue(Properties::getFallthrough( + set->value, getPassOptions(), getModule()->features)); + // Fix up the value. The computation we just did was to look at the + // fallthrough, then precompute that; that looks through expressions + // that pass through the value. Normally that does not matter here, + // for example, (block .. (value)) returns the value unmodified. + // However, some things change the type, for example RefAsNonNull has + // a non-null type, while its input may be nullable. That does not + // matter either, as if we managed to precompute it then the value had + // the more specific (in this example, non-nullable) type. But there + // is a situation where this can cause an issue: RefCast. An attempt to + // perform a "bad" cast, say of a function to a struct, is a case where + // the fallthrough value's type is very different than the actually + // returned value's type. To handle that, if we precomputed a value and + // if it has the wrong type then precompute it again without looking + // through to the fallthrough. + if (values.isConcrete() && + !Type::isSubType(values.getType(), set->value->type)) { + values = precomputeValue(set->value); + } + setValues[set] = values; if (values.isConcrete()) { for (auto* get : localGraph.setInfluences[set]) { work.insert(get); |