Skip to content

Performance regression from Rust 1.37 to 1.38 when using unreachable_unchecked #74615

Open
@nbdd0121

Description

@nbdd0121

I tried this code when looking at the issue #73015.

use std::num::FpCategory;

fn conv(input: usize) -> FpCategory {
    match input {
        0b10000000 | 0b00000001 => FpCategory::Infinite,
        0b01000000 | 0b00000010 => FpCategory::Normal,
        0b00100000 | 0b00000100 => FpCategory::Subnormal,
        0b00010000 | 0b00001000 => FpCategory::Zero,
        0b100000000 | 0b1000000000 => FpCategory::Nan,
        _ => unsafe  { std::hint::unreachable_unchecked() },
    }
}

pub fn test(input: usize) -> bool {
    conv(input) == FpCategory::Zero
}

I expect all other match arms to be optimised out, so basically the code would be equivalent to

pub fn test(input: usize) -> bool {
    match input {
        0b00010000 | 0b00001000 => true
        _ => false,
    }
}

or maybe even

pub fn test(input: usize) -> bool {
    input & 0b00011000 != 0
}

On Rust 1.37 it is quite optimised but a huge chunk of code is generated for 1.38. Interestingly, if the unreachable_unchecked is replaced with a value such as FpCategory::Nan, test could still be optimised.

@rustbot modify labels: +I-slow +I-heavy +T-compiler +A-codegen

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-codegenArea: Code generationC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.I-slowIssue: Problems and improvements with respect to performance of generated code.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions