summaryrefslogtreecommitdiff
path: root/src/cfg/liveness-traversal.h
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2022-04-04 17:21:29 -0700
committerGitHub <noreply@github.com>2022-04-05 00:21:29 +0000
commit18c969e74f14670e52cc9f74c4e76ff197af3f36 (patch)
tree38a300bd08225fd7333ad3f45c8f965f4ac1f918 /src/cfg/liveness-traversal.h
parent0315a5bb3d73ce6c9fe550b3661ec5e78e423520 (diff)
downloadbinaryen-18c969e74f14670e52cc9f74c4e76ff197af3f36.tar.gz
binaryen-18c969e74f14670e52cc9f74c4e76ff197af3f36.tar.bz2
binaryen-18c969e74f14670e52cc9f74c4e76ff197af3f36.zip
[Wasm GC] Fix unreachable local.gets of non-nullable locals in CoalesceLocals (#4574)
Normally we just replace unreachable local.gets with a constant (0, or null), but if the local is non-nullable we can't do that. Fixes #4573
Diffstat (limited to 'src/cfg/liveness-traversal.h')
-rw-r--r--src/cfg/liveness-traversal.h22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/cfg/liveness-traversal.h b/src/cfg/liveness-traversal.h
index 6deab2fd6..ee56a9925 100644
--- a/src/cfg/liveness-traversal.h
+++ b/src/cfg/liveness-traversal.h
@@ -118,7 +118,27 @@ struct LivenessWalker : public CFGWalker<SubType, VisitorType, Liveness> {
auto* curr = (*currp)->cast<LocalGet>();
// if in unreachable code, ignore
if (!self->currBasicBlock) {
- *currp = Builder(*self->getModule()).replaceWithIdenticalType(curr);
+ Builder builder(*self->getModule());
+ auto* rep = builder.replaceWithIdenticalType(curr);
+ if (rep->is<LocalGet>()) {
+ // We failed to replace the node with something simpler. This can happen
+ // if the local is non-nullable, for example. We still need to remove
+ // this node entirely, however, as it is unreachable and so we will not
+ // see it in the analysis we perform (for example, we may be changing
+ // local indexes). Replace it with something completely different, even
+ // if it is larger, a block with a forced type that has unreachable
+ // contents,
+ //
+ // (block (result X)
+ // (unreachable))
+ //
+ // That pattern lets us set any type we wish.
+ //
+ // TODO: Make a helper function for this, if it is useful in other
+ // places.
+ rep = builder.makeBlock({builder.makeUnreachable()}, curr->type);
+ }
+ *currp = rep;
return;
}
self->currBasicBlock->contents.actions.emplace_back(