Closed
Description
I tried this code:
fn last_four(s: &[u8]) -> &[u8] {
let start = if s.len() <= 4 {
0
} else {
s.len() - 4
};
&s[start..]
}
Which produces the following assembly on x86_64:
last_four:
mov rax, rdi
lea rcx, [rsi - 4]
xor edi, edi
cmp rsi, 5
cmovae rdi, rcx
mov rdx, rsi
sub rdx, rdi
jb .LBB0_2
add rax, rdi
ret
.LBB0_2:
push rax
lea rdx, [rip + .L__unnamed_1]
call qword ptr [rip + core::slice::index::slice_start_index_len_fail::hda7fe0c134770be5@GOTPCREL]
.L__unnamed_2:
.ascii "/app/example.rs"
.L__unnamed_1:
.quad .L__unnamed_2
.asciz "\017\000\000\000\000\000\000\000\b\000\000\000\007\000\000"
The branch with the call to slice_start_index_len_fail
should be unreachable.
Indeed, I can remove it by moving the slice operation inside the if
statement:
fn last_four(s: &[u8]) -> &[u8] {
if s.len() <= 4 {
&s[0..]
} else {
&s[s.len() - 4..]
}
}
Which gives:
last_four:
cmp rsi, 5
lea rax, [rdi + rsi - 4]
mov edx, 4
cmovb rdx, rsi
cmovb rax, rdi
ret
Which is what I expected.
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Category: An issue highlighting optimization opportunities or PRs implementing suchCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Issue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.