rust-lang / rust-lang/rust

Incrementing &mut Option<u32> generates verbose instructions 1.94.0 -> 1.95.0

Open
#157,337 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-codegen A-LLVM C-optimization E-needs-bisection I-slow O-x86_32 O-x86_64 P-low regression-from-stable-to-stable S-has-mcve T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code

[Godbolt Link] This is a follow-up to #149970 which, at the time of this writing, has not been resolved yet.

Source:

pub fn f(x: &mut Option<u32>) {
    let mut y = *x;
    y = y.map(|a| a + 1);
    *x = y;
}
// OR
pub fn f(x: &mut Option<u32>) {
    *x = x.map(|a| a + 1);
}

1.94.0's more optimally generated assembly:

f:
        inc     dword ptr [rdi + 4]
        ret

1.95.0's less optimally generated assembly:

f:
        mov     eax, dword ptr [rdi + 4]
        inc     eax
        mov     dword ptr [rdi + 4], eax
        ret
Author's Insights

Within the optimization pipeline, I noticed that the LLVM IR was the same up until the X86 DAG->DAG Instruction Selection (x86-isel) step. The Compiler Explorer link contains a pane to see this.
Although not shown in Godbolt, the regression also exists for x86_32 (i686). See it with Overrides -> Target architecture -> i686-unknown-linux-gnu.

Compilation Info
Rust Edition: 2024
Flags: -C opt-level=3

@rustbot modify labels: +regression-from-stable-to-stable +T-compiler +C-optimization +A-codegen +A-LLVM +E-needs-bisection +S-has-mcve +O-x86_64 +O-x86_32 -C-bug -regression-untriaged

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.

Research direction

Start with the provided Godbolt link and compare the LLVM IR through the x86 DAG->DAG instruction-selection step, then reproduce the regression for both x86_64 and i686 with opt-level=3. Review follow-up issue #149970 and bisect the change between Rust 1.94.0 and 1.95.0. Done means the affected cases once again produce the single-instruction increment shown for 1.94.0.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.