Skip to content

volatile: allow accesses to non-AM memory to trap - #160564

Open
RalfJung wants to merge 2 commits into
rust-lang:mainfrom
RalfJung:volatile-with-trap
Open

volatile: allow accesses to non-AM memory to trap#160564
RalfJung wants to merge 2 commits into
rust-lang:mainfrom
RalfJung:volatile-with-trap

Conversation

@RalfJung

@RalfJung RalfJung commented Aug 5, 2026

Copy link
Copy Markdown
Member

Fixes rust-lang/unsafe-code-guidelines#610 by saying that yes, volatile accesses may trap. This also fixes what I believe to be the last case of "time-traveling UB" we have in Rust: with this change, UB always fully sequenced wrt observable events (I/O and volatile accesses). UB can still travel around unobservable events such as non-volatile memory accesses.

For writes, LLVM has already implemented the new semantics for a long time. For reads, LLVM only recently implemented the "may trap" semantics with LLVM 23. We still allow compiling rustc with older versions of LLVM. To (hopefully) prevent old LLVM from screwing this up with optimizations, this PR makes the backend emit an inline asm block without willreturn, which should prevent optimizations that break programs where a volatile load traps.

Cc @rust-lang/opsem @rust-lang/wg-llvm

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 5, 2026
@rustbot

rustbot commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

r? @jhpratt

rustbot has assigned @jhpratt.
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

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: libs
  • libs expanded to 12 candidates
  • Random selection from JohnTitor, Mark-Simulacrum, clarfonthey, jhpratt, nia-e

@cuviper

cuviper commented Aug 5, 2026

Copy link
Copy Markdown
Member

For reads, LLVM only recently implemented the "may trap" semantics with LLVM 23.

However, fixes for miscompilations often do not get backported to past LLVM versions, so using rustc with older versions of LLVM comes with an increased risk of soundness bugs.

I think the intent here is mainly to acknowledge the existence of bugs in LLVM which independent packagers might want to patch for Rust's sake. It seems quite different to use this for actual UB semantics, because now you're talking about safety guarantees that cannot be upheld (IIUC).

@RalfJung

RalfJung commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

We do sometimes have soundness bugs that are fixed by an LLVM update (so you still have the bug if you use an older LLVM).

But yeah this is different since we'd basically be introducing a new way for rustc+LLVM22 to be wrong rather than just failing to fix an old way. I just don't like having to wait another 6 months for this. :/

I wonder if there's something we can do by using more creative codegen when we are running with LLVM22, like an inline asm block after the volatile read, with that asm not being willreturn. That should prevent LLVM from reordering stuff?

@robofinch

Copy link
Copy Markdown

The access is allowed to trap. It can also cause other side-effects, but those must not affect Rust-allocated memory in any way.

What if the access results in running a signal handler that affects Rust-allocated memory? It seems very desirable for such signal handlers to be sound.

@jhpratt

jhpratt commented Aug 6, 2026

Copy link
Copy Markdown
Member

As a doc-only change, there's no concerns regarding implementation. This solely needs approval from the relevant team (whether that's lang or opsem, not my call).

@RalfJung

RalfJung commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

What if the access results in running a signal handler that affects Rust-allocated memory? It seems very desirable for such signal handlers to be sound.

That's UB. The compiler is allowed to reorder non-volatile accesses around the volatile access.
This PR is specifically about traps (as in, aborting execution). Please take discussion of other effects elsewhere, e.g. a new Zulip thread.

@rustbot rustbot added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Aug 7, 2026
@RalfJung

RalfJung commented Aug 7, 2026

Copy link
Copy Markdown
Member Author

I have added a little hack for LLVM22 and older that inserts a black_box after the volatile read. That should prevent LLVM from moving later UB to before the volatile read, and it makes the intrinsic as a whole non-willreturn. At least I think that's the case, would be good to have a review by an LLVM expert. :)

r? @nikic
(I know you are on vacation, no rush, this can wait)

@rustbot rustbot assigned nikic and unassigned jhpratt Aug 7, 2026
@RalfJung
RalfJung force-pushed the volatile-with-trap branch from 88113e1 to fabe226 Compare August 7, 2026 09:53
@rust-log-analyzer

This comment has been minimized.

@RalfJung
RalfJung force-pushed the volatile-with-trap branch from fabe226 to 93f262f Compare August 7, 2026 10:29
@rust-log-analyzer

This comment has been minimized.

@RalfJung
RalfJung force-pushed the volatile-with-trap branch from 93f262f to de8aff5 Compare August 7, 2026 13:03
@rust-log-analyzer

This comment has been minimized.

@RalfJung
RalfJung force-pushed the volatile-with-trap branch from de8aff5 to 2f2dead Compare August 7, 2026 13:45
@RalfJung

RalfJung commented Aug 7, 2026

Copy link
Copy Markdown
Member Author

Odd, that test doesn't include any volatile, not sure why it would be affected here... is the stack protector logic itself written in Rust and somehow in the same translation unit so the black_box can affect analyses?

Anyway, it seems like that just means some heuristics will work less well with LLVM 22.

@rust-log-analyzer

This comment has been minimized.

@RalfJung

RalfJung commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

With the inline asm "black box" implementation strategy I think this is good to go also for LLVM22 and older.

@rfcbot merge opsem

Cc @rust-lang/lang -- I think this is a sufficiently low-level point that we only need opsem FCP here, but please speak up if you disagree.

@rust-rfcbot

rust-rfcbot commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

@RalfJung has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Aug 8, 2026
@rust-rfcbot rust-rfcbot added the disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. label Aug 8, 2026
@RalfJung RalfJung added I-lang-nominated Nominated for discussion during a lang team meeting. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Aug 8, 2026
@RalfJung RalfJung changed the title volatile: allow accesses to trap volatile: allow accesses to non-AM memory to trap Aug 8, 2026
@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow volatile accesses to trap

9 participants