about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-02-14 16:14:37 +0800
committerkennytm <kennytm@gmail.com>2018-02-14 18:25:14 +0800
commit83bed7d3a7f388422cced710ec5cc82a185c1345 (patch)
tree87b9bfa971bc6e206537399b32e00ef55bdd49b3
parentc02c5f4b606782f0885723e8dfb4249a7691dbf8 (diff)
parentc2a31dee835c2312a9e527b1f9ea1b77c24beeab (diff)
Rollup merge of #48126 - newpavlov:patch-1, r=alexcrichton
Whitelist pclmulqdq x86 feature flag

Relevant `stdsimd` [issue](https://github.com/rust-lang-nursery/stdsimd/issues/318).
-rw-r--r--src/librustc_trans/attributes.rs5
-rw-r--r--src/librustc_trans/llvm_util.rs74
2 files changed, 42 insertions, 37 deletions
diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs
index 6c8088375c4..8309c91ab25 100644
--- a/src/librustc_trans/attributes.rs
+++ b/src/librustc_trans/attributes.rs
@@ -142,7 +142,7 @@ pub fn provide(providers: &mut Providers) {
         assert_eq!(cnum, LOCAL_CRATE);
         Rc::new(llvm_util::target_feature_whitelist(tcx.sess)
             .iter()
-            .map(|c| c.to_str().unwrap().to_string())
+            .map(|c| c.to_string())
             .collect())
     };
 
@@ -212,7 +212,8 @@ fn from_target_feature(
         let value = value.as_str();
         for feature in value.split(',') {
             if whitelist.contains(feature) {
-                target_features.push(format!("+{}", feature));
+                let llvm_feature = llvm_util::to_llvm_feature(feature);
+                target_features.push(format!("+{}", llvm_feature));
                 continue
             }
 
diff --git a/src/librustc_trans/llvm_util.rs b/src/librustc_trans/llvm_util.rs
index 843231d376f..b25562252e7 100644
--- a/src/librustc_trans/llvm_util.rs
+++ b/src/librustc_trans/llvm_util.rs
@@ -14,7 +14,7 @@ use llvm;
 use rustc::session::Session;
 use rustc::session::config::PrintRequest;
 use libc::c_int;
-use std::ffi::{CStr, CString};
+use std::ffi::CString;
 
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Once;
@@ -79,46 +79,53 @@ unsafe fn configure_llvm(sess: &Session) {
 // detection code will walk past the end of the feature array,
 // leading to crashes.
 
-const ARM_WHITELIST: &'static [&'static str] = &["neon\0", "v7\0", "vfp2\0", "vfp3\0", "vfp4\0"];
+const ARM_WHITELIST: &'static [&'static str] = &["neon", "v7", "vfp2", "vfp3", "vfp4"];
 
-const AARCH64_WHITELIST: &'static [&'static str] = &["neon\0", "v7\0"];
+const AARCH64_WHITELIST: &'static [&'static str] = &["neon", "v7"];
 
-const X86_WHITELIST: &'static [&'static str] = &["avx\0", "avx2\0", "bmi\0", "bmi2\0", "sse\0",
-                                                 "sse2\0", "sse3\0", "sse4.1\0", "sse4.2\0",
-                                                 "ssse3\0", "tbm\0", "lzcnt\0", "popcnt\0",
-                                                 "sse4a\0", "rdrnd\0", "rdseed\0", "fma\0",
-                                                 "xsave\0", "xsaveopt\0", "xsavec\0",
-                                                 "xsaves\0", "aes\0",
-                                                 "avx512bw\0", "avx512cd\0",
-                                                 "avx512dq\0", "avx512er\0",
-                                                 "avx512f\0", "avx512ifma\0",
-                                                 "avx512pf\0", "avx512vbmi\0",
-                                                 "avx512vl\0", "avx512vpopcntdq\0",
-                                                 "mmx\0", "fxsr\0"];
+const X86_WHITELIST: &'static [&'static str] = &["avx", "avx2", "bmi", "bmi2", "sse",
+                                                 "sse2", "sse3", "sse4.1", "sse4.2",
+                                                 "ssse3", "tbm", "lzcnt", "popcnt",
+                                                 "sse4a", "rdrnd", "rdseed", "fma",
+                                                 "xsave", "xsaveopt", "xsavec",
+                                                 "xsaves", "aes", "pclmulqdq",
+                                                 "avx512bw", "avx512cd",
+                                                 "avx512dq", "avx512er",
+                                                 "avx512f", "avx512ifma",
+                                                 "avx512pf", "avx512vbmi",
+                                                 "avx512vl", "avx512vpopcntdq",
+                                                 "mmx", "fxsr"];
 
-const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx\0", "hvx-double\0"];
+const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx", "hvx-double"];
 
-const POWERPC_WHITELIST: &'static [&'static str] = &["altivec\0",
-                                                     "power8-altivec\0", "power9-altivec\0",
-                                                     "power8-vector\0", "power9-vector\0",
-                                                     "vsx\0"];
+const POWERPC_WHITELIST: &'static [&'static str] = &["altivec",
+                                                     "power8-altivec", "power9-altivec",
+                                                     "power8-vector", "power9-vector",
+                                                     "vsx"];
 
-const MIPS_WHITELIST: &'static [&'static str] = &["msa\0"];
+const MIPS_WHITELIST: &'static [&'static str] = &["msa"];
+
+pub fn to_llvm_feature(s: &str) -> &str {
+    match s {
+        "pclmulqdq" => "pclmul",
+        s => s,
+    }
+}
 
 pub fn target_features(sess: &Session) -> Vec<Symbol> {
-    let whitelist = target_feature_whitelist(sess);
     let target_machine = create_target_machine(sess);
-    let mut features = Vec::new();
-    for feat in whitelist {
-        if unsafe { llvm::LLVMRustHasFeature(target_machine, feat.as_ptr()) } {
-            features.push(Symbol::intern(feat.to_str().unwrap()));
-        }
-    }
-    features
+    target_feature_whitelist(sess)
+        .iter()
+        .filter(|feature| {
+            let llvm_feature = to_llvm_feature(feature);
+            let cstr = CString::new(llvm_feature).unwrap();
+            unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) }
+        })
+        .map(|feature| Symbol::intern(feature)).collect()
 }
 
-pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> {
-    let whitelist = match &*sess.target.target.arch {
+pub fn target_feature_whitelist(sess: &Session) -> &'static [&'static str] {
+    match &*sess.target.target.arch {
         "arm" => ARM_WHITELIST,
         "aarch64" => AARCH64_WHITELIST,
         "x86" | "x86_64" => X86_WHITELIST,
@@ -126,10 +133,7 @@ pub fn target_feature_whitelist(sess: &Session) -> Vec<&CStr> {
         "mips" | "mips64" => MIPS_WHITELIST,
         "powerpc" | "powerpc64" => POWERPC_WHITELIST,
         _ => &[],
-    };
-    whitelist.iter().map(|m| {
-        CStr::from_bytes_with_nul(m.as_bytes()).unwrap()
-    }).collect()
+    }
 }
 
 pub fn print_version() {