Skip to content

Slice::contains produces worse output than .iter().any #142954

Open
@coastalwhite

Description

@coastalwhite

Version: rustc 1.89.0-nightly (be19eda 2025-06-22)

Link to the Godbolt snippet.
https://godbolt.org/z/q3j8d567v

I tried this code:

// Generates properly optimized code.
pub fn iter_any(v: [u32; 8], x: u32) -> bool {
    v.iter().any(|v| *v == x)
}

// Generates branching code.
pub fn contains(v: [u32; 8], x: u32) -> bool {
    v.contains(&x)
}

I expected both to be the same, or the contains to be more optimal as it is more specialized.

Instead, this happened: the contains seems to generate worse code than iter().any.

Interestingly, if I copy the code directly from core:

pub fn core_impl(v: [u32; 8], x: u32) -> bool {
    // Make our LANE_COUNT 4x the normal lane count (aiming for 128 bit vectors).
    // The compiler will nicely unroll it.
    const LANE_COUNT: usize = 4 * (128 / (size_of::<u32>() * 8));
    // SIMD
    let mut chunks = v.chunks_exact(LANE_COUNT);
    for chunk in &mut chunks {
        if chunk.iter().fold(false, |acc, y| acc | (*y == x)) {
            return true;
        }
    }
    // Scalar remainder
    return chunks.remainder().iter().any(|y| *y == x);
}

This will again generate the better code: https://godbolt.org/z/389GW9c99.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-autovectorizationArea: Autovectorization, which can impact perf or code sizeC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchT-libsRelevant to the library team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions