Here's the code sample where I ran into the problem:
pub fn div(x: u32, y: u32) -> u32 {
x / y
}
pub fn safe_div(x: u32, y: std::num::NonZeroU32) -> u32 {
x / y.get() // an unchecked division expected
}
Godbolt's rustc 1.47.0 -O
generates the same assembly for both functions:
example::div:
push rax
test esi, esi
je .LBB0_2
mov eax, edi
xor edx, edx
div esi
pop rcx
ret
.LBB0_2:
lea rdi, [rip + str.0]
lea rdx, [rip + .L__unnamed_1]
mov esi, 25
call qword ptr [rip + core::panicking::panic@GOTPCREL]
ud2
example::safe_div:
push rax
test esi, esi
je .LBB1_2
mov eax, edi
xor edx, edx
div esi
pop rcx
ret
.LBB1_2:
lea rdi, [rip + str.0]
lea rdx, [rip + .L__unnamed_2]
mov esi, 25
call qword ptr [rip + core::panicking::panic@GOTPCREL]
ud2
However, it is statically known that
checking NonZeroU32::get
's result against zero is pointless.
Can I somehow make the optimizer believe it
(maybe with creating new struct
s for this) in an unsafe
less way?