Skip to content

Excessive overflow checks that can be proven unnecessary #114386

Open
@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.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.llvm-fixed-upstreamIssue expected to be fixed by the next major LLVM upgrade, or backported fixes

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions