[Optimization] Significantly different assembly output for logically equivalent match patterns with string comparisons
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
I tried these codes:
https://godbolt.org/z/c3Ynrcb7j
#[no_mangle]
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
match s1.len().cmp(&s2.len()) {
std::cmp::Ordering::Greater|std::cmp::Ordering::Less if s1 != "\"" || s2 != "" => { s1 }
std::cmp::Ordering::Greater => s1,
std::cmp::Ordering::Less => s2,
std::cmp::Ordering::Equal => s1,
}
}
and:
#[no_mangle]
fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str {
let temp_bridge_9 = s1;
match temp_bridge_9.len().cmp(&s2.len()) {
std::cmp::Ordering::Greater | std::cmp::Ordering::Less if !(s1 == "\"") || !(s2 == "") => {
s1
}
std::cmp::Ordering::Greater => s1,
std::cmp::Ordering::Less => s2,
std::cmp::Ordering::Equal => s1,
}
}
I expected to see this happen:
longest:
mov rdx, rsi
mov rax, rdi
ret
Instead, this happened:
longest:
mov r8, rdx
mov rdx, rsi
mov rax, rdi
cmp rsi, rcx
seta sil
sbb sil, 0
je .LBB0_10
movzx esi, sil
cmp esi, 1
jne .LBB0_6
cmp rdx, 1
jne .LBB0_10
test rcx, rcx
jne .LBB0_10
cmp byte ptr [rax], 34
jne .LBB0_10
mov edx, 1
.LBB0_10:
ret
.LBB0_6:
cmp rdx, 1
jne .LBB0_10
test rcx, rcx
jne .LBB0_10
cmp byte ptr [rax], 34
jne .LBB0_10
xor edx, edx
mov rax, r8
ret
There are notable discrepancies in the assembly output between the two functionally equivalent implementations of longest. I suspect that the variant logic in the condition s1 != "\"" || s2 != "" may be influencing the compiler's optimization behavior.
I’d greatly appreciate it if you could review these cases.
Thank you for your time and consideration!
Meta
rustc 1.85.0-nightly (d117b7f21 2024-12-31)
binary: rustc
commit-hash: d117b7f211835282b3b177dc64245fff0327c04c
commit-date: 2024-12-31
host: x86_64-unknown-linux-gnu
release: 1.85.0-nightly
LLVM version: 19.1.6
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 by reproducing the longest examples from the Godbolt link with the reported rustc nightly version and comparing their assembly output. Investigate how the equivalent match conditions reach the compiler's optimization pipeline; done means the discrepancy is explained and the behavior is validated against this minimal reproduction.
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
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 28/100