rust-lang / rust-lang/rust

MIR optimization produces worse code by losing provenance information

Open
#146,844 5 comments 0 reactions 1 assignee View on GitHub

@nikic is already working on this.

Since Jun 4, 2026.

A-LLVM A-rust-for-linux C-bug I-heavy I-slow T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

unsafe extern "C" {
    safe fn foo();
}

pub fn example() {
    let x = 1;
    println!("{x}");
    if x != 1 {
        foo();
    }
}

With -O, the foo() call cannot be optimized away. It can be optimized away however, if I use -Zmir-opt-level=0.

https://godbolt.org/z/c5qE7Tvsf

My hypothesis is that:

  • format_args takes x by reference
  • This x is annotated as noalias when passing to relevant Argument constructors
  • If inlining is done by LLVM, it makes use of this information and correctly deduce that x cannot change during std::io::stdio::_print
  • If inlining is done by Rust at MIR level, this information is lost, and all LLVM sees is that a pointer is put into Argument and this Argument is passed to std::io::stdio::_print, and hence it has to assume conservatively that the value may change.

This was affecting Rust-for-Linux as we have a build_assert! which performs build-time assertions by requiring calls to be optimized away (Rust equivalent of C's BUILD_BUG_ON), and @joelagnel discovered that adding a print can cause such assertion to trip up.

@rustbot label: +A-rust-for-linux +I-slow +I-heavy

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.