From 18c969e74f14670e52cc9f74c4e76ff197af3f36 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 4 Apr 2022 17:21:29 -0700 Subject: [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 --- src/cfg/liveness-traversal.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src') 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 { auto* curr = (*currp)->cast(); // 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()) { + // 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( -- cgit v1.2.3