Closed
Description
This is born out of https://users.rust-lang.org/t/division-by-nonzero/12822.
The gist is the following function:
pub fn d1(x: u64, y: u64) -> u64 {
x / y.saturating_add(1)
}
generates the following x86_64 assembly:
example::d1:
addq $1, %rsi
movq $-1, %rcx
cmovaeq %rsi, %rcx
testq %rcx, %rcx
je .LBB0_2
xorl %edx, %edx
movq %rdi, %rax
divq %rcx
retq
.LBB0_2:
pushq %rbp
movq %rsp, %rbp
leaq panic_loc.2(%rip), %rdi
callq core::panicking::panic@PLT
str.0:
.ascii "/tmp/compiler-explorer-compiler117811-5-86yrz4.tvuxewb3xr/example.rs"
str.1:
.ascii "attempt to divide by zero"
As far as I can tell, that division cannot panic. If that's true, then the following inefficiences are present:
- The panic basic block that's generated.
- The
testq
andje
instructions are essentially dead.
I don't know the innards of LLVM, but perhaps the non-zero/non-wrapping aspect isn't conveyed to LLVM here? Or perhaps it's not able to figure it out on its own based on whatever IR is given to it.
Metadata
Metadata
Assignees
Labels
Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Category: An issue proposing an enhancement or a PR with one.Issue: Problems and improvements with respect to performance of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.