Skip to content

Adding an assert! prevents bounds check elision #146988

@DCNick3

Description

@DCNick3

I tried this code:

pub fn run_filter( input: &[f32], output: &mut [f32], ) { assert_eq!(input.len(), output.len()); let len = input.len().min(output.len()); for i in 1..len { output[i] = input[i-1] + output[i-1]; } }

I expected all the bounds checks inside the loop to be elided. Since i inside the loop ranges from 1 to min(input.len(), output.len()) and accesses to the slices are done at indices i and i-1, the indices will be in range from 0 to min(input.len(), output.len()), always in bounds.

Instead, as can be seen in this godbolt link, a bounds check is done every iteration of the loop.

If I swap the order of assert and definition of len or remove the assert altogether, the bounds check is successfully elided, also allowing for some loop unrolling.

Seems that adding an assert is somehow preventing optimization here.

Meta

This seems to happen in both stable 1.90 and nightly (rustc version 1.92.0-nightly (975e6c8fe 2025-09-23))

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchE-needs-bisectionCall for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustcI-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions