Skip to content

Vacuum: Do not turn unreachable into nop#8387

Merged
kripken merged 9 commits intoWebAssembly:mainfrom
kripken:vac.unr
Feb 27, 2026
Merged

Vacuum: Do not turn unreachable into nop#8387
kripken merged 9 commits intoWebAssembly:mainfrom
kripken:vac.unr

Conversation

@kripken
Copy link
Member

@kripken kripken commented Feb 25, 2026

This allows propagation of unreachability to callers.

We do not propagate it yet though, so we may want to wait on landing this.

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM whether we want to wait for some kind of propagation or not.

@kripken
Copy link
Member Author

kripken commented Feb 26, 2026

Actually we don't need any propagation 😄 Inlining does it. Added a test to verify.

@kripken
Copy link
Member Author

kripken commented Feb 26, 2026

Fuzzer found this was wrong - effects.trap implies we might trap, not that we must. In rare situations we would end up making code start to trap because of that.

The final fix in this PR is: if code might trap, do not turn it into a nop. That will avoid us turning an unreachable into a nop. It also means we keep around possibly-trapping code, as the new testcase in the last commits shows, but I am pretty sure other passes can handle those cases.

Copy link
Member

@tlively tlively left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little worried that other passes will not handle cleaning up possibly-trapping code. The usual pattern is that other passes depend on Vacuum to do their cleanups for them, not the other way around. Have you verified that this works out in practice?

An alternative approach would be to look for (unreachable) instructions specifically, and Vacuum anything else.

@kripken
Copy link
Member Author

kripken commented Feb 26, 2026

Yeah, I'm worried too, not landing this until we are more certain.

Looking for (unreachable) specifically is not trivial though, as it might be nested inside something, and once it is, we'd need to infer if it actually executes... So in general I just don't think we can turn code into an unreachable here. But also turning it into a nop is bad for propagation...

@tlively
Copy link
Member

tlively commented Feb 26, 2026

I guess I was just thinking about the case where the entire function body has just been reduced to (unreachable) because everything else has been vacuumed up. (The entire function has no unremovable side effects, after all.)

@kripken
Copy link
Member Author

kripken commented Feb 26, 2026

There is also a body that is nothing but (drop (unreachable)). Other passes simplify that, but vacuum can see it. Maybe the best thing is just to scan for an Unreachable anywhere in the code, and never remove that. I pushed that now.

@kripken
Copy link
Member Author

kripken commented Feb 27, 2026

I made this do an extra scan at the end for Unreachables. This situation is rare enough - code that has no effects but trapping - that I'm not worried about the speed of another linear pass.

@kripken kripken merged commit f284d54 into WebAssembly:main Feb 27, 2026
17 checks passed
@kripken kripken deleted the vac.unr branch February 27, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants