Skip to content

Conversation

alexcrichton
Copy link
Member

@alexcrichton alexcrichton commented Sep 11, 2025

This commit is an update to the AbortUnwindingCalls MIR pass in the compiler. Specifically a new boolean is added for "can this target possibly unwind" and if that's false then terminators are all adjusted to be unreachable/not present. The end result is that this fixes #140293 for wasm targets.

The motivation for this PR is that currently on WebAssembly targets the usage of the C-unwind ABI can lead LLVM to either (a) emit exception-handling instructions or (b) hit a LLVM-ICE-style codegen error. WebAssembly as a base instruction set does not support unwinding at all, and a later proposal to WebAssembly, the exception-handling proposal, was what enabled this. This means that the current intent of WebAssembly targets is that they maintain the baseline of "don't emit exception-handling instructions unless enabled". The commit here is intended to restore this behavior by skipping these instructions even when C-unwind is present.

Exception-handling is a relatively tricky and also murky topic in WebAssembly, however. There are two sets of instructions LLVM can emit for WebAssembly exceptions, Rust's Emscripten target supports exceptions, WASI targets do not, the LLVM flags to enable this are not always obvious, and additionally this all touches on "changing exception-handling behavior should be a target-level concern, not a feature". Effectively WebAssembly's exception-handling integration into Rust is not finalized at this time. The best idea at this time is that a parallel set of targets will eventually be added which support exceptions, but it's not clear if/when to do this. In the meantime the goal is to keep existing targets working while still enabling experimentation with exception-handling with -Zbuild-std and various permutations of LLVM flags.

To that extent this commit does not blanket disable these landing pads and cleanup routines for WebAssembly but instead checks to see if panic=unwind is enabled or if +exception-handling is enabled. Tests are updated here as well to account for this where, by default, using a C-unwind ABI won't affect Rust codegen at all. If +exception-handling is enabled, however, then Rust codegen will look like native platforms where exceptions are caught and the program aborts. More-or-less I've done my best to keep exceptions working on wasm where it's possible to have them work, but turned them off where they're not supposed to be emitted.

Closes #140293

@rustbot
Copy link
Collaborator

rustbot commented Sep 11, 2025

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 11, 2025
@rustbot
Copy link
Collaborator

rustbot commented Sep 11, 2025

r? @petrochenkov

rustbot has assigned @petrochenkov.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot

This comment has been minimized.

This commit is an update to the `AbortUnwindingCalls` MIR pass in the
compiler. Specifically a new boolean is added for "can this target
possibly unwind" and if that's `false` then terminators are all adjusted
to be unreachable/not present. The end result is that this fixes 140293
for wasm targets.

The motivation for this PR is that currently on WebAssembly targets the
usage of the `C-unwind` ABI can lead LLVM to either (a) emit
exception-handling instructions or (b) hit a LLVM-ICE-style codegen
error. WebAssembly as a base instruction set does not support unwinding
at all, and a later proposal to WebAssembly, the exception-handling
proposal, was what enabled this. This means that the current intent of
WebAssembly targets is that they maintain the baseline of "don't emit
exception-handling instructions unless enabled". The commit here is
intended to restore this behavior by skipping these instructions even
when `C-unwind` is present.

Exception-handling is a relatively tricky and also murky topic in
WebAssembly, however. There are two sets of instructions LLVM can emit
for WebAssembly exceptions, Rust's Emscripten target supports
exceptions, WASI targets do not, the LLVM flags to enable this are not
always obvious, and additionally this all touches on "changing
exception-handling behavior should be a target-level concern, not a
feature". Effectively WebAssembly's exception-handling integration into
Rust is not finalized at this time. The best idea at this time is that a
parallel set of targets will eventually be added which support
exceptions, but it's not clear if/when to do this. In the meantime the
goal is to keep existing targets working while still enabling
experimentation with exception-handling with `-Zbuild-std` and various
permutations of LLVM flags.

To that extent this commit does not blanket disable these landing pads
and cleanup routines for WebAssembly but instead checks to see if
panic=unwind is enabled or if `+exception-handling` is enabled. Tests
are updated here as well to account for this where, by default, using a
`C-unwind` ABI won't affect Rust codegen at all. If
`+exception-handling` is enabled, however, then Rust codegen will look
like native platforms where exceptions are caught and the program aborts.
More-or-less I've done my best to keep exceptions working on wasm where
it's possible to have them work, but turned them off where they're not
supposed to be emitted.
@petrochenkov
Copy link
Contributor

r? @bjorn3 maybe

@rustbot rustbot assigned bjorn3 and unassigned petrochenkov Sep 14, 2025
@alexcrichton
Copy link
Member Author

ping @bjorn3 would you be ok taking a look at this?

@bjorn3
Copy link
Member

bjorn3 commented Sep 29, 2025

r=me with the test fixed if necessary.

@alexcrichton
Copy link
Member Author

@bors: r=bjorn3

@bors
Copy link
Collaborator

bors commented Sep 29, 2025

📌 Commit 88d7d20 has been approved by bjorn3

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 29, 2025
bors added a commit that referenced this pull request Sep 30, 2025
Rollup of 4 pull requests

Successful merges:

 - #145883 (Make macOS dist build configuration match where reasonable)
 - #146457 (Skip cleanups on unsupported targets)
 - #147152 (builtin `Fn`-trait impls: instantiate binder before the return type `Sized` check)
 - #147153 ([rustdoc] Move doc cfg propagation pass before items stripping passes)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit b310eb9 into rust-lang:master Sep 30, 2025
10 checks passed
@rustbot rustbot added this to the 1.92.0 milestone Sep 30, 2025
rust-timer added a commit that referenced this pull request Sep 30, 2025
Rollup merge of #146457 - alexcrichton:wasm-no-exn-instructions, r=bjorn3

Skip cleanups on unsupported targets

This commit is an update to the `AbortUnwindingCalls` MIR pass in the compiler. Specifically a new boolean is added for "can this target possibly unwind" and if that's `false` then terminators are all adjusted to be unreachable/not present. The end result is that this fixes #140293 for wasm targets.

The motivation for this PR is that currently on WebAssembly targets the usage of the `C-unwind` ABI can lead LLVM to either (a) emit exception-handling instructions or (b) hit a LLVM-ICE-style codegen error. WebAssembly as a base instruction set does not support unwinding at all, and a later proposal to WebAssembly, the exception-handling proposal, was what enabled this. This means that the current intent of WebAssembly targets is that they maintain the baseline of "don't emit exception-handling instructions unless enabled". The commit here is intended to restore this behavior by skipping these instructions even when `C-unwind` is present.

Exception-handling is a relatively tricky and also murky topic in WebAssembly, however. There are two sets of instructions LLVM can emit for WebAssembly exceptions, Rust's Emscripten target supports exceptions, WASI targets do not, the LLVM flags to enable this are not always obvious, and additionally this all touches on "changing exception-handling behavior should be a target-level concern, not a feature". Effectively WebAssembly's exception-handling integration into Rust is not finalized at this time. The best idea at this time is that a parallel set of targets will eventually be added which support exceptions, but it's not clear if/when to do this. In the meantime the goal is to keep existing targets working while still enabling experimentation with exception-handling with `-Zbuild-std` and various permutations of LLVM flags.

To that extent this commit does not blanket disable these landing pads and cleanup routines for WebAssembly but instead checks to see if panic=unwind is enabled or if `+exception-handling` is enabled. Tests are updated here as well to account for this where, by default, using a `C-unwind` ABI won't affect Rust codegen at all. If `+exception-handling` is enabled, however, then Rust codegen will look like native platforms where exceptions are caught and the program aborts. More-or-less I've done my best to keep exceptions working on wasm where it's possible to have them work, but turned them off where they're not supposed to be emitted.

Closes #140293
@bors
Copy link
Collaborator

bors commented Sep 30, 2025

⌛ Testing commit 88d7d20 with merge c5dc558...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exception handling instructions emitted on wasm even when exception-handling feature is disabled
5 participants