Skip to content

LLVM is unable to eliminate bounds checks with widening multiply #65931

@dhardy

Description

@dhardy

Demonstration:

pub fn bar(rand: u32, arr: &[u8]) -> u8 {
    let mul = rand as u64 * arr.len() as u64;
    let hi = (mul >> 32) as u32;
    arr[hi as usize]
}

Note that hi must be less than arr.len(). LLVM is unable to prove this, and inserts a bounds check on array access. Extract from the compiled assembly:

	imulq	%rdx, %rsi
	shrq	$32, %rsi
	cmpq	%rdx, %rsi
	jae	.LBB0_2

Application: rust-random/rand#592

(Note: we have multiple implementations of widening multiply here.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions