Closed
Description
Rustc seems unable to use the fact that NonZeroU64 isn't zero:
use std::num::NonZeroU64;
#[inline(never)]
fn foo(x: u64, y: NonZeroU64) -> u64 {
x / y.get()
}
Gives the asm (with -O):
_ZN4test3foo17h70af812d10d8d714E:
subq $40, %rsp
testq %rdx, %rdx
je .LBB9_2
movq %rdx, %r8
xorl %edx, %edx
movq %rcx, %rax
divq %r8
addq $40, %rsp
retq
.LBB9_2:
leaq .L__unnamed_6(%rip), %rcx
callq _ZN4core9panicking5panic17h6a1e45881f6169d7E
ud2
Adding an assume() solves the problem:
#![feature(core_intrinsics)]
use std::num::NonZeroU64;
use std::intrinsics::assume;
#[inline(never)]
fn foo2(x: u64, y: NonZeroU64) -> u64 {
let y2 = y.get();
unsafe { assume(y2 != 0); }
x / y2
}
_ZN5test24foo217hf17fb494647eabb3E:
movq %rdx, %r8
xorl %edx, %edx
movq %rcx, %rax
divq %r8
retq
Perhaps such assume() should be added at the end of NonZeroU64::get()?