Skip to content

Excessive overflow checks that can be proven unnecessary #114386

@ProgramCrafter

Description

@ProgramCrafter

I tried this code:

#[inline(never)]
fn overflow_check(triple_lim: usize) -> bool {
    let lim: usize = triple_lim / 3;
    lim * 3 >= lim
}

fn main() {
    let n = std::hint::black_box(30);
    println!("{}", overflow_check(n));
}

The check lim * 3 >= lim is trivially true, since lim is obtained by dividing usize by 3 so there can be no overflow. I expected to see it optimized out in ASM, like here (obtained via std::hint::black_box-ing true):

playground::overflow_check:
	movb	$1, -1(%rsp)
	leaq	-1(%rsp), %rax
	#APP
	#NO_APP
	movzbl	-1(%rsp), %eax
	retq

Instead, this happened:

playground::overflow_check:
	movq	%rdi, %rax
	movabsq	$-6148914691236517205, %rcx
	mulq	%rcx
	shrq	%rdx
	leaq	(%rdx,%rdx,2), %rax
	cmpq	%rdx, %rax
	setae	%al
	retq

Meta

https://play.rust-lang.org/?version=stable&mode=release&edition=2021&gist=17cc61a317c18d7ea86d7d98b6a43510

triple_lim >= triple_lim / 3 in a similar test is actually optimized away.

Source

Optimized down from https://rust.godbolt.org/z/jsh6zhPYa (utility function for converting BGR to RGBA arrays).

Metadata

Metadata

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