Skip to content

Missed optimization to elide bounds check #73827

Closed
@a2aaron

Description

@a2aaron

Context: this bug was reduced from indexing into a nested array, but this shows the same problem.

pub fn get(array: &[u8; 8], x: usize, y: usize) -> u8 {
    if x > 7 || y > 7 {
        0
    } else {
        array[y]
    }
}

(Playground link)

Rust doesn't elide the bounds check on array[y], even though it's impossible for y to be out of range due to the if condition. Rust does elide the bounds check when the if condition is just if y > 7, however.

Here is the generated ASM for the above code:

playground::get:
	pushq	%rax
	orq	%rdx, %rsi
	cmpq	$7, %rsi
	jbe	.LBB0_2
	xorl	%eax, %eax
	popq	%rcx
	retq

.LBB0_2:
	cmpq	$7, %rdx
	ja	.LBB0_5
	movb	(%rdi,%rdx), %al
	popq	%rcx
	retq

.LBB0_5:
	leaq	.Lanon.357673f8919c00a2ec2e627b7663c19f.1(%rip), %rax
	movl	$8, %esi
	movq	%rdx, %rdi
	movq	%rax, %rdx
	callq	*core::panicking::panic_bounds_check@GOTPCREL(%rip)
	ud2

.Lanon.357673f8919c00a2ec2e627b7663c19f.0:
	.ascii	"src/lib.rs"

.Lanon.357673f8919c00a2ec2e627b7663c19f.1:
	.quad	.Lanon.357673f8919c00a2ec2e627b7663c19f.0
	.asciz	"\n\000\000\000\000\000\000\000\005\000\000\000\t\000\000"

and here is the generated ASM when we change the if to just be if y > 7

playground::get:
	cmpq	$7, %rdx
	jbe	.LBB0_2
	xorl	%eax, %eax
	retq

.LBB0_2:
	movb	(%rdi,%rdx), %al
	retq

Meta

This occurs in both the latest versions of stable (1.44.1) and nightly (1.46.0-nightly (2020-06-26 7750c3d))

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.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