@@ -106,9 +106,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
106106    { 
107107        // borrows value till the end of this scope: 
108108        let  mut  enable = |r,  rb,  f| { 
109-             if  bit:: test ( r as  usize ,  rb)  { 
109+             let  present = bit:: test ( r as  usize ,  rb) ; 
110+             if  present { 
110111                value. set ( f as  u32 ) ; 
111112            } 
113+             present
112114        } ; 
113115
114116        enable ( proc_info_ecx,  0 ,  Feature :: sse3) ; 
@@ -120,7 +122,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
120122        enable ( proc_info_ecx,  22 ,  Feature :: movbe) ; 
121123        enable ( proc_info_ecx,  23 ,  Feature :: popcnt) ; 
122124        enable ( proc_info_ecx,  25 ,  Feature :: aes) ; 
123-         enable ( proc_info_ecx,  29 ,  Feature :: f16c) ; 
125+         let  f16c =  enable ( proc_info_ecx,  29 ,  Feature :: f16c) ; 
124126        enable ( proc_info_ecx,  30 ,  Feature :: rdrand) ; 
125127        enable ( extended_features_ebx,  18 ,  Feature :: rdseed) ; 
126128        enable ( extended_features_ebx,  19 ,  Feature :: adx) ; 
@@ -216,7 +218,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
216218                    } 
217219
218220                    // FMA (uses 256-bit wide registers): 
219-                     enable ( proc_info_ecx,  12 ,  Feature :: fma) ; 
221+                     let  fma =  enable ( proc_info_ecx,  12 ,  Feature :: fma) ; 
220222
221223                    // And AVX/AVX2: 
222224                    enable ( proc_info_ecx,  28 ,  Feature :: avx) ; 
@@ -235,7 +237,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
235237
236238                    // For AVX-512 the OS also needs to support saving/restoring 
237239                    // the extended state, only then we enable AVX-512 support: 
238-                     if  os_avx512_support { 
240+                     // Also, Rust makes `avx512f` imply `fma` and `f16c`, because 
241+                     // otherwise the assembler is broken. But Intel doesn't guarantee 
242+                     // that `fma` and `f16c` are available with `avx512f`, so we 
243+                     // need to check for them separately. 
244+                     if  os_avx512_support && f16c && fma { 
239245                        enable ( extended_features_ebx,  16 ,  Feature :: avx512f) ; 
240246                        enable ( extended_features_ebx,  17 ,  Feature :: avx512dq) ; 
241247                        enable ( extended_features_ebx,  21 ,  Feature :: avx512ifma) ; 
0 commit comments