Auto merge of #49664 - alexcrichton:stable-simd, r=BurntSushi
Stabilize x86/x86_64 SIMD This commit stabilizes the SIMD in Rust for the x86/x86_64 platforms. Notably this commit is stabilizing: * The `std::arch::{x86, x86_64}` modules and the intrinsics contained inside. * The `is_x86_feature_detected!` macro in the standard library * The `#[target_feature(enable = "...")]` attribute * The `#[cfg(target_feature = "...")]` matcher Stabilization of the module and intrinsics were primarily done in rust-lang-nursery/stdsimd#414 and the two attribute stabilizations are done in this commit. The standard library is also tweaked a bit with the new way that stdsimd is integrated. Note that other architectures like `std::arch::arm` are not stabilized as part of this commit, they will likely stabilize in the future after they've been implemented and fleshed out. Similarly the `std::simd` module is also not being stabilized in this commit, only `std::arch`. Finally, nothing related to `__m64` is stabilized in this commit either (MMX), only SSE and up types and intrinsics are stabilized. Closes #29717 Closes #44839 Closes #48556
This commit is contained in:
commit
186db76159
|
@ -68,7 +68,6 @@
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
#![feature(attr_literals)]
|
#![feature(attr_literals)]
|
||||||
#![feature(cfg_target_feature)]
|
|
||||||
#![feature(cfg_target_has_atomic)]
|
#![feature(cfg_target_has_atomic)]
|
||||||
#![feature(concat_idents)]
|
#![feature(concat_idents)]
|
||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
|
@ -96,11 +95,21 @@
|
||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(stmt_expr_attributes)]
|
#![feature(stmt_expr_attributes)]
|
||||||
#![feature(target_feature)]
|
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
#![feature(untagged_unions)]
|
#![feature(untagged_unions)]
|
||||||
#![feature(unwind_attributes)]
|
#![feature(unwind_attributes)]
|
||||||
|
|
||||||
|
#![cfg_attr(not(stage0), feature(mmx_target_feature))]
|
||||||
|
#![cfg_attr(not(stage0), feature(tbm_target_feature))]
|
||||||
|
#![cfg_attr(not(stage0), feature(sse4a_target_feature))]
|
||||||
|
#![cfg_attr(not(stage0), feature(arm_target_feature))]
|
||||||
|
#![cfg_attr(not(stage0), feature(powerpc_target_feature))]
|
||||||
|
#![cfg_attr(not(stage0), feature(mips_target_feature))]
|
||||||
|
#![cfg_attr(not(stage0), feature(aarch64_target_feature))]
|
||||||
|
|
||||||
|
#![cfg_attr(stage0, feature(target_feature))]
|
||||||
|
#![cfg_attr(stage0, feature(cfg_target_feature))]
|
||||||
|
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
use prelude::v1::*;
|
use prelude::v1::*;
|
||||||
|
@ -204,6 +213,20 @@ mod unit;
|
||||||
// things like SIMD and such. Note that the actual source for all this lies in a
|
// things like SIMD and such. Note that the actual source for all this lies in a
|
||||||
// different repository, rust-lang-nursery/stdsimd. That's why the setup here is
|
// different repository, rust-lang-nursery/stdsimd. That's why the setup here is
|
||||||
// a bit wonky.
|
// a bit wonky.
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! test_v16 { ($item:item) => {}; }
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! test_v32 { ($item:item) => {}; }
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! test_v64 { ($item:item) => {}; }
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! test_v128 { ($item:item) => {}; }
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! test_v256 { ($item:item) => {}; }
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! test_v512 { ($item:item) => {}; }
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! vector_impl { ($([$f:ident, $($args:tt)*]),*) => { $($f!($($args)*);)* } }
|
||||||
#[path = "../stdsimd/coresimd/mod.rs"]
|
#[path = "../stdsimd/coresimd/mod.rs"]
|
||||||
#[allow(missing_docs, missing_debug_implementations, dead_code)]
|
#[allow(missing_docs, missing_debug_implementations, dead_code)]
|
||||||
#[unstable(feature = "stdsimd", issue = "48556")]
|
#[unstable(feature = "stdsimd", issue = "48556")]
|
||||||
|
@ -213,6 +236,6 @@ mod coresimd;
|
||||||
#[unstable(feature = "stdsimd", issue = "48556")]
|
#[unstable(feature = "stdsimd", issue = "48556")]
|
||||||
#[cfg(not(stage0))]
|
#[cfg(not(stage0))]
|
||||||
pub use coresimd::simd;
|
pub use coresimd::simd;
|
||||||
#[unstable(feature = "stdsimd", issue = "48556")]
|
#[stable(feature = "simd_arch", since = "1.27.0")]
|
||||||
#[cfg(not(stage0))]
|
#[cfg(not(stage0))]
|
||||||
pub use coresimd::arch;
|
pub use coresimd::arch;
|
||||||
|
|
|
@ -437,7 +437,7 @@ define_maps! { <'tcx>
|
||||||
substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
|
substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
|
||||||
|
|
||||||
[] fn target_features_whitelist:
|
[] fn target_features_whitelist:
|
||||||
target_features_whitelist_node(CrateNum) -> Lrc<FxHashSet<String>>,
|
target_features_whitelist_node(CrateNum) -> Lrc<FxHashMap<String, Option<String>>>,
|
||||||
|
|
||||||
// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
|
// Get an estimate of the size of an InstanceDef based on its MIR for CGU partitioning.
|
||||||
[] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
|
[] fn instance_def_size_estimate: instance_def_size_estimate_dep_node(ty::InstanceDef<'tcx>)
|
||||||
|
|
|
@ -174,12 +174,12 @@ pub fn provide(providers: &mut Providers) {
|
||||||
// rustdoc needs to be able to document functions that use all the features, so
|
// rustdoc needs to be able to document functions that use all the features, so
|
||||||
// whitelist them all
|
// whitelist them all
|
||||||
Lrc::new(llvm_util::all_known_features()
|
Lrc::new(llvm_util::all_known_features()
|
||||||
.map(|c| c.to_string())
|
.map(|(a, b)| (a.to_string(), b.map(|s| s.to_string())))
|
||||||
.collect())
|
.collect())
|
||||||
} else {
|
} else {
|
||||||
Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
|
Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| c.to_string())
|
.map(|&(a, b)| (a.to_string(), b.map(|s| s.to_string())))
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ use rustc::session::Session;
|
||||||
use rustc::session::config::PrintRequest;
|
use rustc::session::config::PrintRequest;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use syntax::feature_gate::UnstableFeatures;
|
||||||
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
@ -82,40 +83,95 @@ unsafe fn configure_llvm(sess: &Session) {
|
||||||
// to LLVM or the feature detection code will walk past the end of the feature
|
// to LLVM or the feature detection code will walk past the end of the feature
|
||||||
// array, leading to crashes.
|
// array, leading to crashes.
|
||||||
|
|
||||||
const ARM_WHITELIST: &'static [&'static str] = &["neon", "v7", "vfp2", "vfp3", "vfp4"];
|
const ARM_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||||
|
("neon", Some("arm_target_feature")),
|
||||||
|
("v7", Some("arm_target_feature")),
|
||||||
|
("vfp2", Some("arm_target_feature")),
|
||||||
|
("vfp3", Some("arm_target_feature")),
|
||||||
|
("vfp4", Some("arm_target_feature")),
|
||||||
|
];
|
||||||
|
|
||||||
const AARCH64_WHITELIST: &'static [&'static str] = &["fp", "neon", "sve", "crc", "crypto",
|
const AARCH64_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||||
"ras", "lse", "rdm", "fp16", "rcpc",
|
("fp", Some("aarch64_target_feature")),
|
||||||
"dotprod", "v8.1a", "v8.2a", "v8.3a"];
|
("neon", Some("aarch64_target_feature")),
|
||||||
|
("sve", Some("aarch64_target_feature")),
|
||||||
|
("crc", Some("aarch64_target_feature")),
|
||||||
|
("crypto", Some("aarch64_target_feature")),
|
||||||
|
("ras", Some("aarch64_target_feature")),
|
||||||
|
("lse", Some("aarch64_target_feature")),
|
||||||
|
("rdm", Some("aarch64_target_feature")),
|
||||||
|
("fp16", Some("aarch64_target_feature")),
|
||||||
|
("rcpc", Some("aarch64_target_feature")),
|
||||||
|
("dotprod", Some("aarch64_target_feature")),
|
||||||
|
("v8.1a", Some("aarch64_target_feature")),
|
||||||
|
("v8.2a", Some("aarch64_target_feature")),
|
||||||
|
("v8.3a", Some("aarch64_target_feature")),
|
||||||
|
];
|
||||||
|
|
||||||
const X86_WHITELIST: &'static [&'static str] = &["aes", "avx", "avx2", "avx512bw",
|
const X86_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||||
"avx512cd", "avx512dq", "avx512er",
|
("aes", None),
|
||||||
"avx512f", "avx512ifma", "avx512pf",
|
("avx", None),
|
||||||
"avx512vbmi", "avx512vl", "avx512vpopcntdq",
|
("avx2", None),
|
||||||
"bmi1", "bmi2", "fma", "fxsr",
|
("avx512bw", Some("avx512_target_feature")),
|
||||||
"lzcnt", "mmx", "pclmulqdq",
|
("avx512cd", Some("avx512_target_feature")),
|
||||||
"popcnt", "rdrand", "rdseed",
|
("avx512dq", Some("avx512_target_feature")),
|
||||||
"sha",
|
("avx512er", Some("avx512_target_feature")),
|
||||||
"sse", "sse2", "sse3", "sse4.1",
|
("avx512f", Some("avx512_target_feature")),
|
||||||
"sse4.2", "sse4a", "ssse3",
|
("avx512ifma", Some("avx512_target_feature")),
|
||||||
"tbm", "xsave", "xsavec",
|
("avx512pf", Some("avx512_target_feature")),
|
||||||
"xsaveopt", "xsaves"];
|
("avx512vbmi", Some("avx512_target_feature")),
|
||||||
|
("avx512vl", Some("avx512_target_feature")),
|
||||||
|
("avx512vpopcntdq", Some("avx512_target_feature")),
|
||||||
|
("bmi1", None),
|
||||||
|
("bmi2", None),
|
||||||
|
("fma", None),
|
||||||
|
("fxsr", None),
|
||||||
|
("lzcnt", None),
|
||||||
|
("mmx", Some("mmx_target_feature")),
|
||||||
|
("pclmulqdq", None),
|
||||||
|
("popcnt", None),
|
||||||
|
("rdrand", None),
|
||||||
|
("rdseed", None),
|
||||||
|
("sha", None),
|
||||||
|
("sse", None),
|
||||||
|
("sse2", None),
|
||||||
|
("sse3", None),
|
||||||
|
("sse4.1", None),
|
||||||
|
("sse4.2", None),
|
||||||
|
("sse4a", Some("sse4a_target_feature")),
|
||||||
|
("ssse3", None),
|
||||||
|
("tbm", Some("tbm_target_feature")),
|
||||||
|
("xsave", None),
|
||||||
|
("xsavec", None),
|
||||||
|
("xsaveopt", None),
|
||||||
|
("xsaves", None),
|
||||||
|
];
|
||||||
|
|
||||||
const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx", "hvx-double"];
|
const HEXAGON_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||||
|
("hvx", Some("hexagon_target_feature")),
|
||||||
|
("hvx-double", Some("hexagon_target_feature")),
|
||||||
|
];
|
||||||
|
|
||||||
const POWERPC_WHITELIST: &'static [&'static str] = &["altivec",
|
const POWERPC_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||||
"power8-altivec", "power9-altivec",
|
("altivec", Some("powerpc_target_feature")),
|
||||||
"power8-vector", "power9-vector",
|
("power8-altivec", Some("powerpc_target_feature")),
|
||||||
"vsx"];
|
("power9-altivec", Some("powerpc_target_feature")),
|
||||||
|
("power8-vector", Some("powerpc_target_feature")),
|
||||||
|
("power9-vector", Some("powerpc_target_feature")),
|
||||||
|
("vsx", Some("powerpc_target_feature")),
|
||||||
|
];
|
||||||
|
|
||||||
const MIPS_WHITELIST: &'static [&'static str] = &["fp64", "msa"];
|
const MIPS_WHITELIST: &[(&str, Option<&str>)] = &[
|
||||||
|
("fp64", Some("mips_target_feature")),
|
||||||
|
("msa", Some("mips_target_feature")),
|
||||||
|
];
|
||||||
|
|
||||||
/// When rustdoc is running, provide a list of all known features so that all their respective
|
/// When rustdoc is running, provide a list of all known features so that all their respective
|
||||||
/// primtives may be documented.
|
/// primtives may be documented.
|
||||||
///
|
///
|
||||||
/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
|
/// IMPORTANT: If you're adding another whitelist to the above lists, make sure to add it to this
|
||||||
/// iterator!
|
/// iterator!
|
||||||
pub fn all_known_features() -> impl Iterator<Item=&'static str> {
|
pub fn all_known_features() -> impl Iterator<Item=(&'static str, Option<&'static str>)> {
|
||||||
ARM_WHITELIST.iter().cloned()
|
ARM_WHITELIST.iter().cloned()
|
||||||
.chain(AARCH64_WHITELIST.iter().cloned())
|
.chain(AARCH64_WHITELIST.iter().cloned())
|
||||||
.chain(X86_WHITELIST.iter().cloned())
|
.chain(X86_WHITELIST.iter().cloned())
|
||||||
|
@ -144,6 +200,13 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
|
||||||
let target_machine = create_target_machine(sess, true);
|
let target_machine = create_target_machine(sess, true);
|
||||||
target_feature_whitelist(sess)
|
target_feature_whitelist(sess)
|
||||||
.iter()
|
.iter()
|
||||||
|
.filter_map(|&(feature, gate)| {
|
||||||
|
if UnstableFeatures::from_environment().is_nightly_build() || gate.is_none() {
|
||||||
|
Some(feature)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
.filter(|feature| {
|
.filter(|feature| {
|
||||||
let llvm_feature = to_llvm_feature(sess, feature);
|
let llvm_feature = to_llvm_feature(sess, feature);
|
||||||
let cstr = CString::new(llvm_feature).unwrap();
|
let cstr = CString::new(llvm_feature).unwrap();
|
||||||
|
@ -152,7 +215,9 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
|
||||||
.map(|feature| Symbol::intern(feature)).collect()
|
.map(|feature| Symbol::intern(feature)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn target_feature_whitelist(sess: &Session) -> &'static [&'static str] {
|
pub fn target_feature_whitelist(sess: &Session)
|
||||||
|
-> &'static [(&'static str, Option<&'static str>)]
|
||||||
|
{
|
||||||
match &*sess.target.target.arch {
|
match &*sess.target.target.arch {
|
||||||
"arm" => ARM_WHITELIST,
|
"arm" => ARM_WHITELIST,
|
||||||
"aarch64" => AARCH64_WHITELIST,
|
"aarch64" => AARCH64_WHITELIST,
|
||||||
|
|
|
@ -44,7 +44,7 @@ use rustc::middle::cstore::EncodedMetadata;
|
||||||
use rustc::middle::cstore::MetadataLoader;
|
use rustc::middle::cstore::MetadataLoader;
|
||||||
use rustc::dep_graph::DepGraph;
|
use rustc::dep_graph::DepGraph;
|
||||||
use rustc_back::target::Target;
|
use rustc_back::target::Target;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_mir::monomorphize::collector;
|
use rustc_mir::monomorphize::collector;
|
||||||
use link::{build_link_meta, out_filename};
|
use link::{build_link_meta, out_filename};
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ impl TransCrate for MetadataOnlyTransCrate {
|
||||||
::symbol_names::provide(providers);
|
::symbol_names::provide(providers);
|
||||||
|
|
||||||
providers.target_features_whitelist = |_tcx, _cnum| {
|
providers.target_features_whitelist = |_tcx, _cnum| {
|
||||||
Lrc::new(FxHashSet()) // Just a dummy
|
Lrc::new(FxHashMap()) // Just a dummy
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
fn provide_extern(&self, _providers: &mut Providers) {}
|
fn provide_extern(&self, _providers: &mut Providers) {}
|
||||||
|
|
|
@ -37,13 +37,14 @@ use rustc::ty::maps::Providers;
|
||||||
use rustc::ty::util::IntTypeExt;
|
use rustc::ty::util::IntTypeExt;
|
||||||
use rustc::ty::util::Discr;
|
use rustc::ty::util::Discr;
|
||||||
use rustc::util::captures::Captures;
|
use rustc::util::captures::Captures;
|
||||||
use rustc::util::nodemap::{FxHashSet, FxHashMap};
|
use rustc::util::nodemap::FxHashMap;
|
||||||
|
|
||||||
use syntax::{abi, ast};
|
use syntax::{abi, ast};
|
||||||
use syntax::ast::MetaItemKind;
|
use syntax::ast::MetaItemKind;
|
||||||
use syntax::attr::{InlineAttr, list_contains_name, mark_used};
|
use syntax::attr::{InlineAttr, list_contains_name, mark_used};
|
||||||
use syntax::codemap::Spanned;
|
use syntax::codemap::Spanned;
|
||||||
use syntax::symbol::{Symbol, keywords};
|
use syntax::symbol::{Symbol, keywords};
|
||||||
|
use syntax::feature_gate;
|
||||||
use syntax_pos::{Span, DUMMY_SP};
|
use syntax_pos::{Span, DUMMY_SP};
|
||||||
|
|
||||||
use rustc::hir::{self, map as hir_map, TransFnAttrs, TransFnAttrFlags, Unsafety};
|
use rustc::hir::{self, map as hir_map, TransFnAttrs, TransFnAttrFlags, Unsafety};
|
||||||
|
@ -1682,7 +1683,7 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
fn from_target_feature(
|
fn from_target_feature(
|
||||||
tcx: TyCtxt,
|
tcx: TyCtxt,
|
||||||
attr: &ast::Attribute,
|
attr: &ast::Attribute,
|
||||||
whitelist: &FxHashSet<String>,
|
whitelist: &FxHashMap<String, Option<String>>,
|
||||||
target_features: &mut Vec<Symbol>,
|
target_features: &mut Vec<Symbol>,
|
||||||
) {
|
) {
|
||||||
let list = match attr.meta_item_list() {
|
let list = match attr.meta_item_list() {
|
||||||
|
@ -1694,16 +1695,19 @@ fn from_target_feature(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let rust_features = tcx.features();
|
||||||
for item in list {
|
for item in list {
|
||||||
|
// Only `enable = ...` is accepted in the meta item list
|
||||||
if !item.check_name("enable") {
|
if !item.check_name("enable") {
|
||||||
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
|
let msg = "#[target_feature(..)] only accepts sub-keys of `enable` \
|
||||||
currently";
|
currently";
|
||||||
tcx.sess.span_err(item.span, &msg);
|
tcx.sess.span_err(item.span, &msg);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must be of the form `enable = "..."` ( a string)
|
||||||
let value = match item.value_str() {
|
let value = match item.value_str() {
|
||||||
Some(list) => list,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
let msg = "#[target_feature] attribute must be of the form \
|
let msg = "#[target_feature] attribute must be of the form \
|
||||||
#[target_feature(enable = \"..\")]";
|
#[target_feature(enable = \"..\")]";
|
||||||
|
@ -1711,24 +1715,55 @@ fn from_target_feature(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let value = value.as_str();
|
|
||||||
for feature in value.split(',') {
|
|
||||||
if whitelist.contains(feature) {
|
|
||||||
target_features.push(Symbol::intern(feature));
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// We allow comma separation to enable multiple features
|
||||||
|
for feature in value.as_str().split(',') {
|
||||||
|
|
||||||
|
// Only allow whitelisted features per platform
|
||||||
|
let feature_gate = match whitelist.get(feature) {
|
||||||
|
Some(g) => g,
|
||||||
|
None => {
|
||||||
let msg = format!("the feature named `{}` is not valid for \
|
let msg = format!("the feature named `{}` is not valid for \
|
||||||
this target", feature);
|
this target", feature);
|
||||||
let mut err = tcx.sess.struct_span_err(item.span, &msg);
|
let mut err = tcx.sess.struct_span_err(item.span, &msg);
|
||||||
|
|
||||||
if feature.starts_with("+") {
|
if feature.starts_with("+") {
|
||||||
let valid = whitelist.contains(&feature[1..]);
|
let valid = whitelist.contains_key(&feature[1..]);
|
||||||
if valid {
|
if valid {
|
||||||
err.help("consider removing the leading `+` in the feature name");
|
err.help("consider removing the leading `+` in the feature name");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err.emit();
|
err.emit();
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only allow features whose feature gates have been enabled
|
||||||
|
let allowed = match feature_gate.as_ref().map(|s| &**s) {
|
||||||
|
Some("arm_target_feature") => rust_features.arm_target_feature,
|
||||||
|
Some("aarch64_target_feature") => rust_features.aarch64_target_feature,
|
||||||
|
Some("hexagon_target_feature") => rust_features.hexagon_target_feature,
|
||||||
|
Some("powerpc_target_feature") => rust_features.powerpc_target_feature,
|
||||||
|
Some("mips_target_feature") => rust_features.mips_target_feature,
|
||||||
|
Some("avx512_target_feature") => rust_features.avx512_target_feature,
|
||||||
|
Some("mmx_target_feature") => rust_features.mmx_target_feature,
|
||||||
|
Some("sse4a_target_feature") => rust_features.sse4a_target_feature,
|
||||||
|
Some("tbm_target_feature") => rust_features.tbm_target_feature,
|
||||||
|
Some(name) => bug!("unknown target feature gate {}", name),
|
||||||
|
None => true,
|
||||||
|
};
|
||||||
|
if !allowed {
|
||||||
|
feature_gate::emit_feature_err(
|
||||||
|
&tcx.sess.parse_sess,
|
||||||
|
feature_gate.as_ref().unwrap(),
|
||||||
|
item.span,
|
||||||
|
feature_gate::GateIssue::Language,
|
||||||
|
&format!("the target feature `{}` is currently unstable",
|
||||||
|
feature),
|
||||||
|
);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
target_features.push(Symbol::intern(feature));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1835,20 +1870,6 @@ fn trans_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> TransFnAt
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
} else if attr.check_name("target_feature") {
|
} else if attr.check_name("target_feature") {
|
||||||
// handle deprecated #[target_feature = "..."]
|
|
||||||
if let Some(val) = attr.value_str() {
|
|
||||||
for feat in val.as_str().split(",").map(|f| f.trim()) {
|
|
||||||
if !feat.is_empty() && !feat.contains('\0') {
|
|
||||||
trans_fn_attrs.target_features.push(Symbol::intern(feat));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let msg = "#[target_feature = \"..\"] is deprecated and will \
|
|
||||||
eventually be removed, use \
|
|
||||||
#[target_feature(enable = \"..\")] instead";
|
|
||||||
tcx.sess.span_warn(attr.span, &msg);
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
|
if tcx.fn_sig(id).unsafety() == Unsafety::Normal {
|
||||||
let msg = "#[target_feature(..)] can only be applied to \
|
let msg = "#[target_feature(..)] can only be applied to \
|
||||||
`unsafe` function";
|
`unsafe` function";
|
||||||
|
|
|
@ -526,7 +526,7 @@ mod coresimd {
|
||||||
#[unstable(feature = "stdsimd", issue = "48556")]
|
#[unstable(feature = "stdsimd", issue = "48556")]
|
||||||
#[cfg(all(not(stage0), not(test)))]
|
#[cfg(all(not(stage0), not(test)))]
|
||||||
pub use stdsimd::simd;
|
pub use stdsimd::simd;
|
||||||
#[unstable(feature = "stdsimd", issue = "48556")]
|
#[stable(feature = "simd_arch", since = "1.27.0")]
|
||||||
#[cfg(all(not(stage0), not(test)))]
|
#[cfg(all(not(stage0), not(test)))]
|
||||||
pub use stdsimd::arch;
|
pub use stdsimd::arch;
|
||||||
|
|
||||||
|
|
|
@ -231,9 +231,6 @@ declare_features! (
|
||||||
// allow `repr(simd)`, and importing the various simd intrinsics
|
// allow `repr(simd)`, and importing the various simd intrinsics
|
||||||
(active, repr_simd, "1.4.0", Some(27731), None),
|
(active, repr_simd, "1.4.0", Some(27731), None),
|
||||||
|
|
||||||
// Allows cfg(target_feature = "...").
|
|
||||||
(active, cfg_target_feature, "1.4.0", Some(29717), None),
|
|
||||||
|
|
||||||
// allow `extern "platform-intrinsic" { ... }`
|
// allow `extern "platform-intrinsic" { ... }`
|
||||||
(active, platform_intrinsics, "1.4.0", Some(27731), None),
|
(active, platform_intrinsics, "1.4.0", Some(27731), None),
|
||||||
|
|
||||||
|
@ -293,9 +290,6 @@ declare_features! (
|
||||||
|
|
||||||
(active, use_extern_macros, "1.15.0", Some(35896), None),
|
(active, use_extern_macros, "1.15.0", Some(35896), None),
|
||||||
|
|
||||||
// Allows #[target_feature(...)]
|
|
||||||
(active, target_feature, "1.15.0", None, None),
|
|
||||||
|
|
||||||
// `extern "ptx-*" fn()`
|
// `extern "ptx-*" fn()`
|
||||||
(active, abi_ptx, "1.15.0", None, None),
|
(active, abi_ptx, "1.15.0", None, None),
|
||||||
|
|
||||||
|
@ -446,6 +440,17 @@ declare_features! (
|
||||||
|
|
||||||
// Allows macro invocations in `extern {}` blocks
|
// Allows macro invocations in `extern {}` blocks
|
||||||
(active, macros_in_extern, "1.27.0", Some(49476), None),
|
(active, macros_in_extern, "1.27.0", Some(49476), None),
|
||||||
|
|
||||||
|
// unstable #[target_feature] directives
|
||||||
|
(active, arm_target_feature, "1.27.0", None, None),
|
||||||
|
(active, aarch64_target_feature, "1.27.0", None, None),
|
||||||
|
(active, hexagon_target_feature, "1.27.0", None, None),
|
||||||
|
(active, powerpc_target_feature, "1.27.0", None, None),
|
||||||
|
(active, mips_target_feature, "1.27.0", None, None),
|
||||||
|
(active, avx512_target_feature, "1.27.0", None, None),
|
||||||
|
(active, mmx_target_feature, "1.27.0", None, None),
|
||||||
|
(active, sse4a_target_feature, "1.27.0", None, None),
|
||||||
|
(active, tbm_target_feature, "1.27.0", None, None),
|
||||||
);
|
);
|
||||||
|
|
||||||
declare_features! (
|
declare_features! (
|
||||||
|
@ -568,6 +573,10 @@ declare_features! (
|
||||||
(accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
|
(accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
|
||||||
// Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
|
// Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
|
||||||
(accepted, generic_param_attrs, "1.26.0", Some(48848), None),
|
(accepted, generic_param_attrs, "1.26.0", Some(48848), None),
|
||||||
|
// Allows cfg(target_feature = "...").
|
||||||
|
(accepted, cfg_target_feature, "1.27.0", Some(29717), None),
|
||||||
|
// Allows #[target_feature(...)]
|
||||||
|
(accepted, target_feature, "1.27.0", None, None),
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you change this, please modify src/doc/unstable-book as well. You must
|
// If you change this, please modify src/doc/unstable-book as well. You must
|
||||||
|
@ -912,10 +921,7 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
|
||||||
"the `#[naked]` attribute \
|
"the `#[naked]` attribute \
|
||||||
is an experimental feature",
|
is an experimental feature",
|
||||||
cfg_fn!(naked_functions))),
|
cfg_fn!(naked_functions))),
|
||||||
("target_feature", Whitelisted, Gated(
|
("target_feature", Normal, Ungated),
|
||||||
Stability::Unstable, "target_feature",
|
|
||||||
"the `#[target_feature]` attribute is an experimental feature",
|
|
||||||
cfg_fn!(target_feature))),
|
|
||||||
("export_name", Whitelisted, Ungated),
|
("export_name", Whitelisted, Ungated),
|
||||||
("inline", Whitelisted, Ungated),
|
("inline", Whitelisted, Ungated),
|
||||||
("link", Whitelisted, Ungated),
|
("link", Whitelisted, Ungated),
|
||||||
|
@ -1046,7 +1052,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
|
||||||
// cfg(...)'s that are feature gated
|
// cfg(...)'s that are feature gated
|
||||||
const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[
|
const GATED_CFGS: &[(&str, &str, fn(&Features) -> bool)] = &[
|
||||||
// (name in cfg, feature, function to check if the feature is enabled)
|
// (name in cfg, feature, function to check if the feature is enabled)
|
||||||
("target_feature", "cfg_target_feature", cfg_fn!(cfg_target_feature)),
|
|
||||||
("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)),
|
("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)),
|
||||||
("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)),
|
("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)),
|
||||||
("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)),
|
("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)),
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit bcb720e55861c38db47f2ebdf26b7198338cb39d
|
Subproject commit effdcd0132d17b6c4badc67b4b6d3fdf749a2d22
|
|
@ -11,6 +11,7 @@
|
||||||
// ignore-emscripten
|
// ignore-emscripten
|
||||||
|
|
||||||
#![feature(repr_simd, target_feature, cfg_target_feature)]
|
#![feature(repr_simd, target_feature, cfg_target_feature)]
|
||||||
|
#![feature(avx512_target_feature)]
|
||||||
|
|
||||||
use std::process::{Command, ExitStatus};
|
use std::process::{Command, ExitStatus};
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#[cfg(target_feature = "x")] //~ ERROR `cfg(target_feature)` is experimental
|
|
||||||
#[cfg_attr(target_feature = "x", x)] //~ ERROR `cfg(target_feature)` is experimental
|
|
||||||
struct Foo(u64, u64);
|
|
||||||
|
|
||||||
#[cfg(not(any(all(target_feature = "x"))))] //~ ERROR `cfg(target_feature)` is experimental
|
|
||||||
fn foo() {}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
cfg!(target_feature = "x");
|
|
||||||
//~^ ERROR `cfg(target_feature)` is experimental and subject to change
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717)
|
|
||||||
--> $DIR/feature-gate-cfg-target-feature.rs:12:12
|
|
||||||
|
|
|
||||||
LL | #[cfg_attr(target_feature = "x", x)] //~ ERROR `cfg(target_feature)` is experimental
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: add #![feature(cfg_target_feature)] to the crate attributes to enable
|
|
||||||
|
|
||||||
error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717)
|
|
||||||
--> $DIR/feature-gate-cfg-target-feature.rs:11:7
|
|
||||||
|
|
|
||||||
LL | #[cfg(target_feature = "x")] //~ ERROR `cfg(target_feature)` is experimental
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: add #![feature(cfg_target_feature)] to the crate attributes to enable
|
|
||||||
|
|
||||||
error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717)
|
|
||||||
--> $DIR/feature-gate-cfg-target-feature.rs:15:19
|
|
||||||
|
|
|
||||||
LL | #[cfg(not(any(all(target_feature = "x"))))] //~ ERROR `cfg(target_feature)` is experimental
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: add #![feature(cfg_target_feature)] to the crate attributes to enable
|
|
||||||
|
|
||||||
error[E0658]: `cfg(target_feature)` is experimental and subject to change (see issue #29717)
|
|
||||||
--> $DIR/feature-gate-cfg-target-feature.rs:19:10
|
|
||||||
|
|
|
||||||
LL | cfg!(target_feature = "x");
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: add #![feature(cfg_target_feature)] to the crate attributes to enable
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
|
@ -1,13 +0,0 @@
|
||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#[target_feature = "+sse2"]
|
|
||||||
//~^ the `#[target_feature]` attribute is an experimental feature
|
|
||||||
fn foo() {}
|
|
|
@ -1,11 +0,0 @@
|
||||||
error[E0658]: the `#[target_feature]` attribute is an experimental feature
|
|
||||||
--> $DIR/feature-gate-target_feature.rs:11:1
|
|
||||||
|
|
|
||||||
LL | #[target_feature = "+sse2"]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= help: add #![feature(target_feature)] to the crate attributes to enable
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// ignore-arm
|
||||||
|
// ignore-aarch64
|
||||||
|
// ignore-wasm
|
||||||
|
// ignore-emscripten
|
||||||
|
// gate-test-sse4a_target_feature
|
||||||
|
// gate-test-powerpc_target_feature
|
||||||
|
// gate-test-avx512_target_feature
|
||||||
|
// gate-test-tbm_target_feature
|
||||||
|
// gate-test-arm_target_feature
|
||||||
|
// gate-test-aarch64_target_feature
|
||||||
|
// gate-test-hexagon_target_feature
|
||||||
|
// gate-test-mips_target_feature
|
||||||
|
// gate-test-mmx_target_feature
|
||||||
|
// min-llvm-version 6.0
|
||||||
|
|
||||||
|
#[target_feature(enable = "avx512bw")]
|
||||||
|
//~^ ERROR: currently unstable
|
||||||
|
unsafe fn foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
error[E0658]: the target feature `avx512bw` is currently unstable
|
||||||
|
--> $DIR/target-feature-gate.rs:26:18
|
||||||
|
|
|
||||||
|
LL | #[target_feature(enable = "avx512bw")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: add #![feature(avx512_target_feature)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
|
@ -19,7 +19,7 @@
|
||||||
#![feature(target_feature)]
|
#![feature(target_feature)]
|
||||||
|
|
||||||
#[target_feature = "+sse2"]
|
#[target_feature = "+sse2"]
|
||||||
//~^ WARN: deprecated
|
//~^ ERROR: must be of the form
|
||||||
#[target_feature(enable = "foo")]
|
#[target_feature(enable = "foo")]
|
||||||
//~^ ERROR: not valid for this target
|
//~^ ERROR: not valid for this target
|
||||||
#[target_feature(bar)]
|
#[target_feature(bar)]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
warning: #[target_feature = ".."] is deprecated and will eventually be removed, use #[target_feature(enable = "..")] instead
|
error: #[target_feature] attribute must be of the form #[target_feature(..)]
|
||||||
--> $DIR/target-feature-wrong.rs:21:1
|
--> $DIR/target-feature-wrong.rs:21:1
|
||||||
|
|
|
|
||||||
LL | #[target_feature = "+sse2"]
|
LL | #[target_feature = "+sse2"]
|
||||||
|
@ -43,5 +43,5 @@ error: cannot use #[inline(always)] with #[target_feature]
|
||||||
LL | #[inline(always)]
|
LL | #[inline(always)]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue