Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Lokathor opened this issue Sep 16, 2019 · 6 comments
Open
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@Lokathor
Copy link
Contributor

Lokathor commented Sep 16, 2019

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.

@jonas-schievink jonas-schievink added C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Sep 16, 2019
@hanna-kruppe
Copy link
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).

@Lokathor
Copy link
Contributor Author

Lokathor commented Sep 18, 2019

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.

@programmerjake
Copy link
Member

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

@ChaiTRex
Copy link
Contributor

ChaiTRex commented Oct 3, 2023

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.

@jamesmunns
Copy link
Member

jamesmunns commented Jan 19, 2024

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

@ChaiTRex
Copy link
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
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants