rust-lang / rust-lang/rust

Return values from certain calls receive unnecessarily separate stack slots due to MIR passes

Open
#161,506 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug needs-triage
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Compiler Explorer reproduction: https://godbolt.org/z/r3M8MY5ea [Disclosure: LLM-minimized repro case]

The relevant bit is async fn f, which repeatedly awaits a future that has a large output type. The lifetimes of the return values from each await don't overlap, but they end up with separate stack slots anyway, ballooning the stack frame. See the sub rsp, 1032 in the assembly; this frame size increases linearly with each if let Some(x) = F.await { return x; } iteration you add. Appears to be architecture-independent.

This seems to be a bug that occurs separately in the CopyProp, GVN, and DestinationPropagation MIR passes, where StorageLive and StorageDead markers get mistakenly dropped for await-result temporaries. Passing -Zmir-enable-passes=-CopyProp,-GVN,-DestinationPropagation results in a stack frame size that isn't affected by the number of awaits (but only when all 3 are disabled together). Demo here: https://godbolt.org/z/4Kfe9fYjY

This appears to repro at least as far back as 1.82, and as recently as current nightlies.

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 Compiler Explorer reproductions and inspect the MIR transformations in CopyProp, GVN, and DestinationPropagation. Compare how StorageLive and StorageDead are handled for await-result temporaries, using the three-pass-disable variant as a control. Done means repeated awaits no longer cause linear stack-frame growth while the relevant MIR behavior remains correct.

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
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.