Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vec::IntoIter<[T]>::next generates unnecessary null checking #106368

Closed
AnsonYeung opened this issue Jan 2, 2023 · 0 comments
Closed

vec::IntoIter<[T]>::next generates unnecessary null checking #106368

AnsonYeung opened this issue Jan 2, 2023 · 0 comments

Comments

@AnsonYeung
Copy link

AnsonYeung commented Jan 2, 2023

For the following code, it seems the compiler was unable to optimize away the loop for the first 2 functions.

pub fn vec(foo: Vec<&[i32]>) -> usize {
    into_iter_last(foo.into_iter())
}

pub fn vec2(foo: Vec<&[i32]>) -> usize {
    into_iter_last(foo.into_iter().map(|s| *&s))
}

pub fn vec3(foo: Vec<&[i32]>) -> usize {
    into_iter_last(foo.iter().map(|s| *s))
}

pub fn slice(foo: &[&[i32]]) -> usize {
    into_iter_last(foo.into_iter().map(|s| *s))
}

pub fn into_iter_last<'a>(mut foo: impl Iterator<Item = &'a [i32]>) -> usize {
    let mut res = 0;
    while let Some(slice) = foo.next() {
        res = slice.len();
    }
    res
}

This seems to be only happening for Vec and not slice. Seems like the compiler forgets that slice ptr cannot be null and unable to optimize away the loop.

https://rust.godbolt.org/z/7EvqWE7vv

example::vec:
        push    rbx
        mov     rax, rdi
        mov     rsi, qword ptr [rdi]
        mov     rdi, qword ptr [rdi + 8]
        mov     rax, qword ptr [rax + 16]
        test    rax, rax
        je      .LBB0_6
        cmp     qword ptr [rdi], 0
        je      .LBB0_6
        shl     rax, 4
        mov     edx, 16
.LBB0_3:
        mov     rcx, rdx
        cmp     rax, rdx
        je      .LBB0_5
        lea     rdx, [rcx + 16]
        cmp     qword ptr [rdi + rcx], 0  ; unnecessary null check
        jne     .LBB0_3
.LBB0_5:
        mov     rbx, qword ptr [rdi + rcx - 8]
        test    rsi, rsi
        jne     .LBB0_7
        jmp     .LBB0_8
.LBB0_6:
        xor     ebx, ebx
        test    rsi, rsi
        je      .LBB0_8
.LBB0_7:
        shl     rsi, 4
        mov     edx, 8
        call    qword ptr [rip + __rust_dealloc@GOTPCREL]
.LBB0_8:
        mov     rax, rbx
        pop     rbx
        ret

example::vec2:
        push    rbx
        mov     rax, rdi
        mov     rsi, qword ptr [rdi]
        mov     rdi, qword ptr [rdi + 8]
        mov     rax, qword ptr [rax + 16]
        test    rax, rax
        je      .LBB1_6
        cmp     qword ptr [rdi], 0  ; unnecessary null check
        je      .LBB1_6
        shl     rax, 4
        mov     edx, 16
.LBB1_3:
        mov     rcx, rdx
        cmp     rax, rdx
        je      .LBB1_5
        lea     rdx, [rcx + 16]
        cmp     qword ptr [rdi + rcx], 0
        jne     .LBB1_3
.LBB1_5:
        mov     rbx, qword ptr [rdi + rcx - 8]
        test    rsi, rsi
        jne     .LBB1_7
        jmp     .LBB1_8
.LBB1_6:
        xor     ebx, ebx
        test    rsi, rsi
        je      .LBB1_8
.LBB1_7:
        shl     rsi, 4
        mov     edx, 8
        call    qword ptr [rip + __rust_dealloc@GOTPCREL]
.LBB1_8:
        mov     rax, rbx
        pop     rbx
        ret

example::vec3:
        push    rbx
        mov     rax, rdi
        mov     rdi, qword ptr [rdi + 8]
        mov     rcx, qword ptr [rax + 16]
        test    rcx, rcx
        je      .LBB2_1
        shl     rcx, 4
        mov     rbx, qword ptr [rcx + rdi - 8]
        mov     rsi, qword ptr [rax]
        test    rsi, rsi
        je      .LBB2_5
.LBB2_4:
        shl     rsi, 4
        mov     edx, 8
        call    qword ptr [rip + __rust_dealloc@GOTPCREL]
.LBB2_5:
        mov     rax, rbx
        pop     rbx
        ret
.LBB2_1:
        xor     ebx, ebx
        mov     rsi, qword ptr [rax]
        test    rsi, rsi
        jne     .LBB2_4
        jmp     .LBB2_5

example::slice:
        test    rsi, rsi
        je      .LBB3_1
        shl     rsi, 4
        mov     rax, qword ptr [rsi + rdi - 8]
        ret
.LBB3_1:
        xor     eax, eax
        ret
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

No branches or pull requests

1 participant