Skip to content

Conversation

@coolreader18
Copy link

@coolreader18 coolreader18 commented Dec 1, 2025

Closes #195

With this change, this function in a downstream crate:

pub fn foo(x: &[u8], y: u8) -> &[u8] {
    match memchr::memchr(y, x) {
        Some(i) => &x[i..],
        None => &[],
    }
}

Generates this assembly:

Assembly output
foobar::foo:
	push r14
	push rbx
	push rax
	mov eax, edx
	mov rbx, rsi
	mov r14, rdi
	lea rdx, [rdi + rsi]
	mov rcx, qword ptr [rip + memchr::arch::x86_64::memchr::memchr_raw::FN@GOTPCREL]
	mov rcx, qword ptr [rcx]
	mov edi, eax
	mov rsi, r14
	call rcx
	mov rcx, rax
	test cl, 1
	je .LBB0_1
	mov rax, rdx
	sub r14, rdx
	add rbx, r14
	jmp .LBB0_2
.LBB0_1:
	mov eax, 1
	xor ebx, ebx
.LBB0_2:
	mov rdx, rbx
	add rsp, 8
	pop rbx
	pop r14
	ret

Whereas before, it would include a branch to core::slice::index::slice_index_fail.

This only works for the oneshot functions, not memchr_iter, since Iter doesn't hold a reference to the original slice. To get the same effect there, I think you'd have to add a original_len: usize field to Iter, which isn't that crazy but maybe seems silly to only use it for an optimization hint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider hinting to the compiler that indices returned from memchr() are within bounds of the haystack

1 participant