Skip to content

Needed: cfg(target_feature) support for hardware floating point detection. #64514

Open

Description

@Lokathor

Currently there seems to be no way to detect at compile time if the target will have hardware floating point support.

Depending on the target arch, this is sometimes expressed in LLVM as a feature named "hard-float", or as a feature named "soft-float", or even as features named "f" and "d". It's entirely possible for there to be hardware f32 support but not f64 support on some platforms. LLVM has (or should have) all of this info already, based on the target profile. We just don't expose it in Rust.

For the record, this is initially needed for libm/compiler-builtins to advance the issue of moving sqrt and other float support into core, so if this is added as some sort of Nightly-only and perma-unstable ability then that's probably fine since those crates are always built with Nightly and then shipped with the compiler.

It feels like this could be a simple PR thing by someone who knows about that part of the cargo/LLVM/rustc interaction, but more likely this is some sort of RFC level change. However, it's also possible that I'm totally wrong and that there is already an arcane way to check for floating point support configuration already, so I'm starting with an issue to try and get some visibility for the problem.

Activity

  1. added
    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.
    T-langRelevant to the language team
    on Sep 16, 2019
  2. hanna-kruppe commented on Sep 18, 2019

    @hanna-kruppe
    Contributor

    Trying to classify chips as "has / lacks hardware support for floating point" (even if f32 and f64 are distinguished) is too coarse-grained and runs into too many edge cases to be useful IMO.

    Since you mentioned sqrt as motivation: it is perfectly possible to implement the basic arithmetic operations in hardware but lack a hardware sqrt instructions, which means you definitely have "hardware floating point" but still need a libcall for sqrt. This is not hypothetical: some early MIPS chips (like the R2000 with FPU coprocessor) and Nyuzi both did this. Admittedly I don't believe this is a good trade-off for general-purpose processors these days and the majority of CPU architectures do provide a sqrt instruction if they , but (1) nobody forces designers to make good decisions and (2) specific domains might have different needs.

    Other operations such as trigonometric functions are even more complicated, hardware implementations are far from the norm and even when they exist they rarely have enough precision to be used by default, but they're still widely used with -ffast-math.

    IMO it might make more sense to expose whether specific operations (or small related groups of operations) have hardware support in a specific context (e.g., set of target features), but this should be done case-by-case and tailored to concrete use cases (such as sqrt-in-libcore).

  3. Lokathor commented on Sep 18, 2019

    @Lokathor
    ContributorAuthor

    Unfortunately that low level of granularity is the granularity that the LLVM target features deal in.

    To be clear, if the target device has a hardware sqrt ability but it's not configured for the current build, because the user did something like "+soft-float" on their x86_64, we must respect that. Which is why we need to divine what target features are being used for this build or not.

  4. programmerjake commented on Oct 3, 2023

    @programmerjake
    Member

    for sqrt specifically, rustc could just query llvm's TargetTransformInfo::haveFastSqrt

  5. ChaiTRex commented on Oct 3, 2023

    @ChaiTRex
    Contributor

    for sqrt specifically, rustc could just query llvm's TargetTransformInfo::haveFastSqrt

    I don't know LLVM, but it seems like it takes a type, so maybe it could tell us f32 and f64 separately, which would be good.

    One use I'd like to put it to is #116226, as there are different fastest implementations for all four combinations of f32 or f64 having or not having sqrt hardware acceleration.

  6. jamesmunns commented on Jan 19, 2024

    @jamesmunns
    Contributor

    Also noting this is useful beyond sqrt detection, cortex-m-rt uses the target string, detected via an env var, whether to enable/initialize the FPU at startup, by smuggling a non-feature cfg flag:

    detection: https://github.com/rust-embedded/cortex-m/blob/6b3a5b7fb95fe98fb05ddb4270d2d14709afe99c/cortex-m-rt/build.rs#L63-L65

    conditional code: https://github.com/rust-embedded/cortex-m/blob/6b3a5b7fb95fe98fb05ddb4270d2d14709afe99c/cortex-m-rt/src/lib.rs#L554-L564

  7. ChaiTRex commented on Feb 28, 2024

    @ChaiTRex
    Contributor

    The Linux kernel and drivers make system calls faster by forbidding floating point operations. It seems to enforce that in Rust by using #![no_std] and making some floating point Rust intrinsics panic.

    Is this the only way that it enforces it?

    If that's the only way it enforces it, then in addition to asking the compiler backend whether a specific floating point operation is accelerated, we'd also need to check whether those particular intrinsics have been set to panic. To be clear, if those intrinsics are set to panic, any floating point operations, including those not set to panic, should report that they are not hardware accelerated, because some are available in core through core::intrinsics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions