Skip to content

is_riscv_feature_detected doesn't seem to actually detect anything at runtime #139139

New issue

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

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

Already on GitHub? # to your account

Open
ThomasHabets opened this issue Mar 30, 2025 · 4 comments
Assignees
Labels
A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug. O-riscv Target: RISC-V architecture T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@ThomasHabets
Copy link

ThomasHabets commented Mar 30, 2025

I tried this code

fn check_rvv() {
    let enabled = cfg!(target_feature="v");
    let detected = std::arch::is_riscv_feature_detected!("v");
    println!("RVV enabled={enabled} detected={detected}");
}  

I expected to see this happen

Any way at all under hardware with and without RVV support, with and without -Ctarget-feature=+v, to be able to return something other than "enabled and detected", or "not enabled and not detected".

I.e. for this feature to be useful for:

  1. Saying: Hey, you have a CPU capable of vector instructions, but this binary is not, or
  2. Having a hand coded RVV function, built with #[target_feature(enable = "v")], that can be selected at runtime, while the rest of the Rust code does not assume +v.

I do realise that if I compile with +v (thus cfg!(target_feature = "v") returns true everywhere), then the binary will probably be broken on non-rvv hardware. E.g. println!() could use the very instructions that are not supported, so I can't even print an error.

But for the cases above:

  1. Should be safe, just tell user to rebuild.
  2. It's apparently not actually runtime detecting anything.

Instead, this happened

It seems that if -Ctarget-feature=+v is not enabled, then std::arch::is_riscv_feature_detected!("v") always returns false.

It's also curious that inside a #[target_feature(enable = "v")] function, cfg!(target_feature="v") doesn't return true, unless the whole program was built with +v. Is that working as intended?

It seems to me that this should not be the same as #138789, where the reason is that LLVM doesn't have the CPU in its database. Because if it were, then the example code should never show enabled=true detected=true, but it does.

Not sure if it helps at all, but the code base I'm working on is rvv-vroom. You can run the code related to this bug using cargo +nightly run.

Meta

rustc --version --verbose:

$ cargo +nightly version --verbose
cargo 1.87.0-nightly (6cf826701 2025-03-14)
release: 1.87.0-nightly
commit-hash: 6cf8267012570f63d6b86e85a2ae5627de52df9e
commit-date: 2025-03-14
host: riscv64gc-unknown-linux-gnu
libgit2: 1.9.0 (sys:0.20.0 vendored)
libcurl: 8.12.1-DEV (sys:0.4.80+curl-8.12.1 vendored ssl:OpenSSL/3.4.1)
ssl: OpenSSL 3.4.1 11 Feb 2025
os: Ubuntu 24.4.0 (noble) [64-bit]
@ThomasHabets ThomasHabets added the C-bug Category: This is a bug. label Mar 30, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 30, 2025
@taiki-e
Copy link
Member

taiki-e commented Mar 30, 2025

The result of is_riscv_feature_detected!("v") becomes false even though it is available on the CPU, because runtime detection of the v target feature is not yet implemented.

#138789 is unrelated because we and LLVM implement feature detection in different places.

As always, this can be implemented by adjust & upstream what is in the portable-atomic.

@rustbot claim
@rustbot label +O-RISCV

@rustbot rustbot added the O-riscv Target: RISC-V architecture label Mar 30, 2025
@ehuss
Copy link
Contributor

ehuss commented Mar 30, 2025

It's also curious that inside a #[target_feature(enable = "v")] function, cfg!(target_feature="v") doesn't return true, unless the whole program was built with +v. Is that working as intended?

I believe this is #42515. cfg does not know about #[target_feature] attributes.

@Noratrieb Noratrieb added T-libs Relevant to the library team, which will review and decide on the PR/issue. A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 30, 2025
@taiki-e
Copy link
Member

taiki-e commented Mar 30, 2025

Filed rust-lang/stdarch#1762 for is_riscv_feature_detected.

@a4lg
Copy link
Contributor

a4lg commented Apr 21, 2025

rust-lang/stdarch#1770 (based on @taiki-e's rust-lang/stdarch#1762) is merged so that large portions of supported extensions can be detected by runtime.

And, to avoid pitfalls finding an extension / using something after depending extension is detected, I filed rust-lang/stdarch#1779 which adds the platform guide documentation.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug. O-riscv Target: RISC-V architecture T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants