Bounds check not elided for `slice::split_at` after loop
Open
Nobody has claimed this yet.
C-optimization
T-compiler
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
split_at panics when mid > len.
In the following code for trimming the start of a slice, i will only be less than or equal to len but the information seems lost after the loop.
#[inline(never)]
pub fn src(s: &[u8]) -> &[u8] {
let mut i = 0;
while i < s.len() {
if s[i] != 0 {
break;
}
i += 1;
}
s.split_at(i).1
}
#[inline(never)]
pub const fn tgt(s: &[u8]) -> &[u8] {
let mut i = 0;
while i < s.len() {
if s[i] != 0 {
return s.split_at(i).1;
}
i += 1;
}
&[]
}
https://rust.godbolt.org/z/EWPbf4Pdd
Assembly output
src functionexample::src::he3649242b6e21a77:
xor eax, eax
test rsi, rsi
je .LBB0_6
.LBB0_1:
cmp byte ptr [rdi + rax], 0
jne .LBB0_5
inc rax
cmp rsi, rax
jne .LBB0_1
mov rax, rsi
jmp .LBB0_6
.LBB0_5:
cmp rax, rsi
ja .LBB0_4
.LBB0_6:
add rdi, rax
sub rsi, rax
mov rax, rdi
mov rdx, rsi
ret
.LBB0_4:
sub rsp, 56
lea rax, [rip + .Lanon.7d93f8663e2093497ca272392f600a6e.1]
mov qword ptr [rsp + 8], rax
mov qword ptr [rsp + 16], 1
mov qword ptr [rsp + 24], 8
xorps xmm0, xmm0
movups xmmword ptr [rsp + 32], xmm0
lea rsi, [rip + .Lanon.7d93f8663e2093497ca272392f600a6e.3]
lea rdi, [rsp + 8]
call qword ptr [rip + core::panicking::panic_fmt::hf1310915e65e5ab4@GOTPCREL]
.Lanon.7d93f8663e2093497ca272392f600a6e.0:
.ascii "mid > len"
.Lanon.7d93f8663e2093497ca272392f600a6e.1:
.quad .Lanon.7d93f8663e2093497ca272392f600a6e.0
.asciz "\t\000\000\000\000\000\000"
.Lanon.7d93f8663e2093497ca272392f600a6e.2:
.asciz "/app/example.rs"
.Lanon.7d93f8663e2093497ca272392f600a6e.3:
.quad .Lanon.7d93f8663e2093497ca272392f600a6e.2
.asciz "\020\000\000\000\000\000\000\000\n\000\000\000\007\000\000"
tgt function
example::tgt::hfc7b3a5f713674dc:
mov eax, 1
test rsi, rsi
je .LBB0_1
mov rdx, rsi
.LBB0_4:
cmp byte ptr [rdi], 0
jne .LBB0_5
inc rdi
dec rdx
jne .LBB0_4
.LBB0_1:
xor edx, edx
ret
.LBB0_5:
mov rax, rdi
ret
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 provided src and tgt reproducer and compare their assembly output using the linked Rust Compiler Explorer example. Investigate how slice::split_at handles the loop's range information, and consider the work complete when the equivalent src case no longer emits the unnecessary bounds check while preserving its behavior.
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
- Mostly clear
- Newbie friendliness
- 38/100