Skip to content

Obvious bounds checks don't get optimized unless I add a if+panic #90794

Closed
@elichai

Description

@elichai

I'm writing code to rank a matrix and the compiler doesn't see it can remove bounds checks even though it's obvious.
But if I add a check on the index the compiler can then remove the bounds checks.
The minimal code to reproduce it:

pub fn compute_rank(mat_float: [[f64; 64]; 64]) -> usize {
    const EPS: f64 = 1e-9;
    let row_selected = [false; 64];
    for i in 0..64 {
        for j in 0..64 {
            if !row_selected[j] && mat_float[j][i] > EPS {
                break;
            }
        }
    }
    0
}

godbolt: https://godbolt.org/z/xjhMq3TrY

But when adding an if+panic the bounds checks get removed: (even though the assume is obvious)

pub fn compute_rank(mat_float: [[f64; 64]; 64]) -> usize {
    const EPS: f64 = 1e-9;
    let row_selected = [false; 64];
    for i in 0..64 {
        if i >= 64 {panic!("This should never happen")}
        for j in 0..64 {
            if !row_selected[j] && mat_float[j][i] > EPS {
                break;
            }
        }
    }
    0
}

https://godbolt.org/z/Ecvd4e9nM

(The full code is obviously longer and contain more bounds checks that all get eliminated by this check)

(Originally I used unreachable_unchecked() for this but somehow even an if+panic solves this)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.I-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