Redundant memory stores with mut parameters in by-value returns
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Godbolt link
https://godbolt.org/z/W8xxse95v
Summary
When a function takes a mut parameter and returns the same type by value, the compiler generates redundant memory stores compared to using semantically equivalent let mut rebinding.
Code Examples
pub struct SomeComplexType {
a: u64,
b: u64,
c: u64,
}
// Version 1: with `mut` parameter (problematic - generates redundant stores)
#[inline(never)]
pub fn with_mut_param(mut a: SomeComplexType) -> SomeComplexType {
a.a += 10;
a.b += 2;
a
}
// Version 2: with `let mut` rebinding (optimal - no redundant stores)
#[inline(never)]
pub fn with_rebind(a: SomeComplexType) -> SomeComplexType {
let mut a = a;
a.a += 10;
a.b += 2;
a
}
Expected Behavior
Both functions should generate identical optimal assembly (like with_rebind), since they are semantically equivalent.
Actual Behavior
compiled with --target=riscv64gc-unknown-linux-gnu -C opt-level=3
this bug can also be seen on x86_64
example::with_rebind::h8093d7779180c3d2:
ld a2, 0(a1) # load a.a
ld a3, 8(a1) # load a.b
ld a1, 16(a1) # load a.c
addi a2, a2, 10 # a.a+=10
addi a3, a3, 2 # a.b+=2
sd a2, 0(a0) #store a.a to return
sd a3, 8(a0) #store a.b to return
sd a1, 16(a0) #store a.c to return
ret
example::with_mut_param::hd013a2ed7fc4bb64:
ld a2, 0(a1) # load a.a
ld a3, 8(a1) # load a.b
ld a4, 16(a1) # load a.c
addi a2, a2, 10 # a.a+=10
addi a3, a3, 2 # a.b+=2
sd a2, 0(a1) # REDUNDANT: store back to source (a.a)
sd a3, 8(a1) # REDUNDANT: store back to source (a.b)
sd a2, 0(a0) # store a.a to return
sd a3, 8(a0) # store a.b to return
sd a4, 16(a0) # store a.c to return
ret
Meta
This bug exists in rustc 1.91.0 and both nightly and beta compilers at November 8
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
Reproduce the two functions from the Godbolt link with rustc 1.91.0 at opt-level=3 for riscv64gc-unknown-linux-gnu and x86_64, then compare their generated assembly. Trace where the mut-parameter version introduces the stores shown in the report and verify that the completed change produces assembly matching with_rebind without changing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100