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"
https://godbolt.org/g/8eh61N
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 and je 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.
This is born out of https://users.rust-lang.org/t/division-by-nonzero/12822.
The gist is the following function:
generates the following x86_64 assembly:
https://godbolt.org/g/8eh61N
As far as I can tell, that division cannot panic. If that's true, then the following inefficiences are present:
testqandjeinstructions 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.