Return values from certain calls receive unnecessarily separate stack slots due to MIR passes
Nobody has claimed this yet.
- 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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