summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-05-31 14:45:42 -0700
committerGitHub <noreply@github.com>2022-05-31 21:45:42 +0000
commit6257a5857a42fec6b86352b03c1e92dcb7a490ea (patch)
tree26169d49d4f095e0f84d0d9d9e01a691e1173e2b /src
parentc4988562f9ed04400fc348bf99d5709cf063d96e (diff)
downloadbinaryen-6257a5857a42fec6b86352b03c1e92dcb7a490ea.tar.gz
binaryen-6257a5857a42fec6b86352b03c1e92dcb7a490ea.tar.bz2
binaryen-6257a5857a42fec6b86352b03c1e92dcb7a490ea.zip
[WasmGC] Fix try-catch and non-nullable local sets in values in SimplifyLocals (#4705)
Followup to #4703, this also handles the case where there is a non- nullable local.set in the value of a nullable one, which we also cannot optimize. Fixes #4702
Diffstat (limited to 'src')
-rw-r--r--src/passes/SimplifyLocals.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp
index 5cf3b8241..159f09963 100644
--- a/src/passes/SimplifyLocals.cpp
+++ b/src/passes/SimplifyLocals.cpp
@@ -306,8 +306,12 @@ struct SimplifyLocals
for (auto& [index, info] : self->sinkables) {
// Expressions that may throw cannot be moved into a try (which might
// catch them, unlike before the move).
- //
- // Also, non-nullable local.sets cannot be moved into a try, as that may
+ if (info.effects.throws()) {
+ invalidated.push_back(index);
+ continue;
+ }
+
+ // Non-nullable local.sets cannot be moved into a try, as that may
// change dominance from the perspective of the spec
//
// (local.set $x X)
@@ -338,9 +342,17 @@ struct SimplifyLocals
// dominance). To stay compliant with the spec, however, we must not
// move code regardless of whether ".." can throw - we must simply keep
// the set outside of the try.
- if (info.effects.throws() ||
- self->getFunction()->getLocalType(index).isNonNullable()) {
- invalidated.push_back(index);
+ //
+ // The problem described can also occur on the *value* and not the set
+ // itself. For example, |X| above could be a local.set of a non-nullable
+ // local. For that reason we must scan it all.
+ if (self->getModule()->features.hasGCNNLocals()) {
+ for (auto* set : FindAll<LocalSet>(*info.item).list) {
+ if (self->getFunction()->getLocalType(set->index).isNonNullable()) {
+ invalidated.push_back(index);
+ break;
+ }
+ }
}
}
for (auto index : invalidated) {