Open
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
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Relating to patterns and pattern matchingCategory: An issue highlighting optimization opportunities or PRs implementing suchIssue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
saethlin commentedon Apr 21, 2025
Alive2 says the the optimization is valid: https://alive2.llvm.org/ce/z/4amEw6
WindFrank commentedon Apr 21, 2025
@saethlin If alive2 confirms it's valid, would it make sense to implement this optimization in LLVM/Rust?
saethlin commentedon Apr 21, 2025
When alive2 says a transformation is valid between the two optimized LLVM IR outputs, it means that the improvement can be implemented in LLVM.
If alive2 doesn't say that the transformation is valid, sometimes the two programs just behave differently, and sometimes we are not giving LLVM all the information that makes the optimization valid.
I've added A-LLVM and I-slow because there are some LLVM contributors that watch our issue tracker for those labels.
WindFrank commentedon Apr 21, 2025
@saethlin I see. Thank you for your explanation. I truly hope this issue can contribute to rustc and LLVM.