about summary refs log tree commit diff
path: root/library/stdarch/crates/std_detect
diff options
context:
space:
mode:
authorsayantn <sayantn05@gmail.com>2025-04-18 12:03:16 +0530
committerAmanieu d'Antras <amanieu@gmail.com>2025-05-01 11:37:00 +0000
commit4d665d1a017b3bc5bc8a91e4c86e4c8b07ff7987 (patch)
tree71d99a37ae9250a8c75917cacc2cd93c2d840c0b /library/stdarch/crates/std_detect
parented25a9bde4102f00e0cef5b784f3a57347f896f9 (diff)
downloadrust-4d665d1a017b3bc5bc8a91e4c86e4c8b07ff7987.tar.gz
rust-4d665d1a017b3bc5bc8a91e4c86e4c8b07ff7987.zip
Require `fma` and `f16c` for `avx512f` in `std_detect`
Diffstat (limited to 'library/stdarch/crates/std_detect')
-rw-r--r--library/stdarch/crates/std_detect/src/detect/os/x86.rs14
1 files changed, 10 insertions, 4 deletions
diff --git a/library/stdarch/crates/std_detect/src/detect/os/x86.rs b/library/stdarch/crates/std_detect/src/detect/os/x86.rs
index e48d04ad004..8565c2f85e2 100644
--- a/library/stdarch/crates/std_detect/src/detect/os/x86.rs
+++ b/library/stdarch/crates/std_detect/src/detect/os/x86.rs
@@ -106,9 +106,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
     {
         // borrows value till the end of this scope:
         let mut enable = |r, rb, f| {
-            if bit::test(r as usize, rb) {
+            let present = bit::test(r as usize, rb);
+            if present {
                 value.set(f as u32);
             }
+            present
         };
 
         enable(proc_info_ecx, 0, Feature::sse3);
@@ -120,7 +122,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
         enable(proc_info_ecx, 22, Feature::movbe);
         enable(proc_info_ecx, 23, Feature::popcnt);
         enable(proc_info_ecx, 25, Feature::aes);
-        enable(proc_info_ecx, 29, Feature::f16c);
+        let f16c = enable(proc_info_ecx, 29, Feature::f16c);
         enable(proc_info_ecx, 30, Feature::rdrand);
         enable(extended_features_ebx, 18, Feature::rdseed);
         enable(extended_features_ebx, 19, Feature::adx);
@@ -216,7 +218,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
                     }
 
                     // FMA (uses 256-bit wide registers):
-                    enable(proc_info_ecx, 12, Feature::fma);
+                    let fma = enable(proc_info_ecx, 12, Feature::fma);
 
                     // And AVX/AVX2:
                     enable(proc_info_ecx, 28, Feature::avx);
@@ -235,7 +237,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
 
                     // For AVX-512 the OS also needs to support saving/restoring
                     // the extended state, only then we enable AVX-512 support:
-                    if os_avx512_support {
+                    // Also, Rust makes `avx512f` imply `fma` and `f16c`, because
+                    // otherwise the assembler is broken. But Intel doesn't guarantee
+                    // that `fma` and `f16c` are available with `avx512f`, so we
+                    // need to check for them separately.
+                    if os_avx512_support && f16c && fma {
                         enable(extended_features_ebx, 16, Feature::avx512f);
                         enable(extended_features_ebx, 17, Feature::avx512dq);
                         enable(extended_features_ebx, 21, Feature::avx512ifma);