Skip to content

Division by nonzero #54868

Closed
Closed
@leonardo-m

Description

@leonardo-m

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()?

Metadata

Metadata

Assignees

No one assigned

    Labels

    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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions