Rollup merge of #128192 - mrkajetanp:feature-detect, r=Amanieu
rustc_target: Add various aarch64 features Add various aarch64 features already supported by LLVM and Linux. Additionally include some comment fixes to ensure consistency of feature names with the Arm ARM. Compiler support for features added to stdarch by https://github.com/rust-lang/stdarch/pull/1614. Tracking issue for unstable aarch64 features is https://github.com/rust-lang/rust/issues/127764. List of added features: - FEAT_CSSC - FEAT_ECV - FEAT_FAMINMAX - FEAT_FLAGM2 - FEAT_FP8 - FEAT_FP8DOT2 - FEAT_FP8DOT4 - FEAT_FP8FMA - FEAT_HBC - FEAT_LSE128 - FEAT_LSE2 - FEAT_LUT - FEAT_MOPS - FEAT_LRCPC3 - FEAT_SVE_B16B16 - FEAT_SVE2p1 - FEAT_WFxT - FEAT_SME - FEAT_SME_F16F16 - FEAT_SME_F64F64 - FEAT_SME_F8F16 - FEAT_SME_F8F32 - FEAT_SME_FA64 - FEAT_SME_I16I64 - FEAT_SME_LUTv2 - FEAT_SME2 - FEAT_SME2p1 - FEAT_SSVE_FP8DOT2 - FEAT_SSVE_FP8DOT4 - FEAT_SSVE_FP8FMA FEAT_FPMR is added in the first commit and then removed in a separate one to highlight it being removed from upstream LLVM 19. The intention is for it to be detectable at runtime through stdarch but not have a corresponding Rust compile-time feature.
This commit is contained in:
commit
4c8c9e092d
@ -521,13 +521,20 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||
|
||||
let function_features = function_features
|
||||
.iter()
|
||||
.flat_map(|feat| {
|
||||
llvm_util::to_llvm_features(cx.tcx.sess, feat).into_iter().map(|f| format!("+{f}"))
|
||||
})
|
||||
// Convert to LLVMFeatures and filter out unavailable ones
|
||||
.flat_map(|feat| llvm_util::to_llvm_features(cx.tcx.sess, feat))
|
||||
// Convert LLVMFeatures & dependencies to +<feats>s
|
||||
.flat_map(|feat| feat.into_iter().map(|f| format!("+{f}")))
|
||||
.chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x {
|
||||
InstructionSetAttr::ArmA32 => "-thumb-mode".to_string(),
|
||||
InstructionSetAttr::ArmT32 => "+thumb-mode".to_string(),
|
||||
}))
|
||||
// HACK: LLVM versions 19+ do not have the FPMR feature and treat it as always enabled
|
||||
// It only exists as a feature in LLVM 18, cannot be passed down for any other version
|
||||
.chain(match &*cx.tcx.sess.target.arch {
|
||||
"aarch64" if llvm_util::get_version().0 == 18 => vec!["+fpmr".to_string()],
|
||||
_ => vec![],
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
if cx.tcx.sess.target.is_like_wasm {
|
||||
|
@ -209,7 +209,7 @@ fn into_iter(self) -> Self::IntoIter {
|
||||
// Though note that Rust can also be build with an external precompiled version of LLVM
|
||||
// which might lead to failures if the oldest tested / supported LLVM version
|
||||
// doesn't yet support the relevant intrinsics
|
||||
pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
|
||||
pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFeature<'a>> {
|
||||
let arch = if sess.target.arch == "x86_64" {
|
||||
"x86"
|
||||
} else if sess.target.arch == "arm64ec" {
|
||||
@ -218,40 +218,59 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a
|
||||
&*sess.target.arch
|
||||
};
|
||||
match (arch, s) {
|
||||
("x86", "sse4.2") => {
|
||||
LLVMFeature::with_dependency("sse4.2", TargetFeatureFoldStrength::EnableOnly("crc32"))
|
||||
}
|
||||
("x86", "pclmulqdq") => LLVMFeature::new("pclmul"),
|
||||
("x86", "rdrand") => LLVMFeature::new("rdrnd"),
|
||||
("x86", "bmi1") => LLVMFeature::new("bmi"),
|
||||
("x86", "cmpxchg16b") => LLVMFeature::new("cx16"),
|
||||
("x86", "lahfsahf") => LLVMFeature::new("sahf"),
|
||||
("aarch64", "rcpc2") => LLVMFeature::new("rcpc-immo"),
|
||||
("aarch64", "dpb") => LLVMFeature::new("ccpp"),
|
||||
("aarch64", "dpb2") => LLVMFeature::new("ccdp"),
|
||||
("aarch64", "frintts") => LLVMFeature::new("fptoint"),
|
||||
("aarch64", "fcma") => LLVMFeature::new("complxnum"),
|
||||
("aarch64", "pmuv3") => LLVMFeature::new("perfmon"),
|
||||
("aarch64", "paca") => LLVMFeature::new("pauth"),
|
||||
("aarch64", "pacg") => LLVMFeature::new("pauth"),
|
||||
("x86", "sse4.2") => Some(LLVMFeature::with_dependency(
|
||||
"sse4.2",
|
||||
TargetFeatureFoldStrength::EnableOnly("crc32"),
|
||||
)),
|
||||
("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")),
|
||||
("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")),
|
||||
("x86", "bmi1") => Some(LLVMFeature::new("bmi")),
|
||||
("x86", "cmpxchg16b") => Some(LLVMFeature::new("cx16")),
|
||||
("x86", "lahfsahf") => Some(LLVMFeature::new("sahf")),
|
||||
("aarch64", "rcpc2") => Some(LLVMFeature::new("rcpc-immo")),
|
||||
("aarch64", "dpb") => Some(LLVMFeature::new("ccpp")),
|
||||
("aarch64", "dpb2") => Some(LLVMFeature::new("ccdp")),
|
||||
("aarch64", "frintts") => Some(LLVMFeature::new("fptoint")),
|
||||
("aarch64", "fcma") => Some(LLVMFeature::new("complxnum")),
|
||||
("aarch64", "pmuv3") => Some(LLVMFeature::new("perfmon")),
|
||||
("aarch64", "paca") => Some(LLVMFeature::new("pauth")),
|
||||
("aarch64", "pacg") => Some(LLVMFeature::new("pauth")),
|
||||
("aarch64", "sve-b16b16") => Some(LLVMFeature::new("b16b16")),
|
||||
("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")),
|
||||
// Rust ties fp and neon together.
|
||||
("aarch64", "neon") => {
|
||||
LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8"))
|
||||
Some(LLVMFeature::with_dependency("neon", TargetFeatureFoldStrength::Both("fp-armv8")))
|
||||
}
|
||||
// In LLVM neon implicitly enables fp, but we manually enable
|
||||
// neon when a feature only implicitly enables fp
|
||||
("aarch64", "fhm") => LLVMFeature::new("fp16fml"),
|
||||
("aarch64", "fp16") => LLVMFeature::new("fullfp16"),
|
||||
("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
|
||||
("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")),
|
||||
// Filter out features that are not supported by the current LLVM version
|
||||
("aarch64", "faminmax") if get_version().0 < 18 => None,
|
||||
("aarch64", "fp8") if get_version().0 < 18 => None,
|
||||
("aarch64", "fp8dot2") if get_version().0 < 18 => None,
|
||||
("aarch64", "fp8dot4") if get_version().0 < 18 => None,
|
||||
("aarch64", "fp8fma") if get_version().0 < 18 => None,
|
||||
("aarch64", "fpmr") if get_version().0 != 18 => None,
|
||||
("aarch64", "lut") if get_version().0 < 18 => None,
|
||||
("aarch64", "sme-f8f16") if get_version().0 < 18 => None,
|
||||
("aarch64", "sme-f8f32") if get_version().0 < 18 => None,
|
||||
("aarch64", "sme-fa64") if get_version().0 < 18 => None,
|
||||
("aarch64", "sme-lutv2") if get_version().0 < 18 => None,
|
||||
("aarch64", "ssve-fp8dot2") if get_version().0 < 18 => None,
|
||||
("aarch64", "ssve-fp8dot4") if get_version().0 < 18 => None,
|
||||
("aarch64", "ssve-fp8fma") if get_version().0 < 18 => None,
|
||||
("aarch64", "v9.5a") if get_version().0 < 18 => None,
|
||||
// In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called
|
||||
// `fast-unaligned-access`. In LLVM 19, it was split back out.
|
||||
("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
|
||||
LLVMFeature::new("fast-unaligned-access")
|
||||
Some(LLVMFeature::new("fast-unaligned-access"))
|
||||
}
|
||||
// For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled.
|
||||
("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => {
|
||||
LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512"))
|
||||
Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
|
||||
}
|
||||
(_, s) => LLVMFeature::new(s),
|
||||
(_, s) => Some(LLVMFeature::new(s)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,13 +310,17 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
|
||||
return true;
|
||||
}
|
||||
// check that all features in a given smallvec are enabled
|
||||
for llvm_feature in to_llvm_features(sess, feature) {
|
||||
let cstr = SmallCStr::new(llvm_feature);
|
||||
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
|
||||
return false;
|
||||
if let Some(feat) = to_llvm_features(sess, feature) {
|
||||
for llvm_feature in feat {
|
||||
let cstr = SmallCStr::new(llvm_feature);
|
||||
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
true
|
||||
})
|
||||
.map(|(feature, _, _)| Symbol::intern(feature)),
|
||||
);
|
||||
@ -386,9 +409,9 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
|
||||
.target
|
||||
.supported_target_features()
|
||||
.iter()
|
||||
.map(|(feature, _gate, _implied)| {
|
||||
.filter_map(|(feature, _gate, _implied)| {
|
||||
// LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
|
||||
let llvm_feature = to_llvm_features(sess, *feature).llvm_feature_name;
|
||||
let llvm_feature = to_llvm_features(sess, *feature)?.llvm_feature_name;
|
||||
let desc =
|
||||
match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {
|
||||
Some(index) => {
|
||||
@ -398,7 +421,7 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
|
||||
None => "",
|
||||
};
|
||||
|
||||
(*feature, desc)
|
||||
Some((*feature, desc))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -595,7 +618,7 @@ pub(crate) fn global_llvm_features(
|
||||
if feature_state.is_none() {
|
||||
let rust_feature =
|
||||
supported_features.iter().find_map(|&(rust_feature, _, _)| {
|
||||
let llvm_features = to_llvm_features(sess, rust_feature);
|
||||
let llvm_features = to_llvm_features(sess, rust_feature)?;
|
||||
if llvm_features.contains(feature)
|
||||
&& !llvm_features.contains(rust_feature)
|
||||
{
|
||||
@ -641,7 +664,7 @@ pub(crate) fn global_llvm_features(
|
||||
// passing requests down to LLVM. This means that all in-language
|
||||
// features also work on the command line instead of having two
|
||||
// different names when the LLVM name and the Rust name differ.
|
||||
let llvm_feature = to_llvm_features(sess, feature);
|
||||
let llvm_feature = to_llvm_features(sess, feature)?;
|
||||
|
||||
Some(
|
||||
std::iter::once(format!(
|
||||
@ -691,6 +714,9 @@ fn backend_feature_name<'a>(sess: &Session, s: &'a str) -> Option<&'a str> {
|
||||
let feature = s
|
||||
.strip_prefix(&['+', '-'][..])
|
||||
.unwrap_or_else(|| sess.dcx().emit_fatal(InvalidTargetFeaturePrefix { feature: s }));
|
||||
if s.is_empty() {
|
||||
return None;
|
||||
}
|
||||
// Rustc-specific feature requests like `+crt-static` or `-crt-static`
|
||||
// are not passed down to LLVM.
|
||||
if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
|
||||
|
@ -302,6 +302,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
// FIXME: Document these and merge with the list below.
|
||||
|
||||
// Unstable `#[target_feature]` directives.
|
||||
(unstable, aarch64_unstable_target_feature, "CURRENT_RUSTC_VERSION", Some(44839)),
|
||||
(unstable, aarch64_ver_target_feature, "1.27.0", Some(44839)),
|
||||
(unstable, arm_target_feature, "1.27.0", Some(44839)),
|
||||
(unstable, avx512_target_feature, "1.27.0", Some(44839)),
|
||||
|
@ -356,6 +356,7 @@
|
||||
_task_context,
|
||||
a32,
|
||||
aarch64_target_feature,
|
||||
aarch64_unstable_target_feature,
|
||||
aarch64_ver_target_feature,
|
||||
abi,
|
||||
abi_amdgpu_kernel,
|
||||
|
@ -99,6 +99,8 @@ pub fn is_stable(self) -> bool {
|
||||
("bti", Stable, &[]),
|
||||
// FEAT_CRC
|
||||
("crc", Stable, &[]),
|
||||
// FEAT_CSSC
|
||||
("cssc", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_DIT
|
||||
("dit", Stable, &[]),
|
||||
// FEAT_DotProd
|
||||
@ -107,21 +109,37 @@ pub fn is_stable(self) -> bool {
|
||||
("dpb", Stable, &[]),
|
||||
// FEAT_DPB2
|
||||
("dpb2", Stable, &["dpb"]),
|
||||
// FEAT_ECV
|
||||
("ecv", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_F32MM
|
||||
("f32mm", Stable, &["sve"]),
|
||||
// FEAT_F64MM
|
||||
("f64mm", Stable, &["sve"]),
|
||||
// FEAT_FAMINMAX
|
||||
("faminmax", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_FCMA
|
||||
("fcma", Stable, &["neon"]),
|
||||
// FEAT_FHM
|
||||
("fhm", Stable, &["fp16"]),
|
||||
// FEAT_FLAGM
|
||||
("flagm", Stable, &[]),
|
||||
// FEAT_FLAGM2
|
||||
("flagm2", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_FP16
|
||||
// Rust ties FP and Neon: https://github.com/rust-lang/rust/pull/91608
|
||||
("fp16", Stable, &["neon"]),
|
||||
// FEAT_FP8
|
||||
("fp8", Unstable(sym::aarch64_unstable_target_feature), &["faminmax", "lut", "bf16"]),
|
||||
// FEAT_FP8DOT2
|
||||
("fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["fp8dot4"]),
|
||||
// FEAT_FP8DOT4
|
||||
("fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["fp8fma"]),
|
||||
// FEAT_FP8FMA
|
||||
("fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["fp8"]),
|
||||
// FEAT_FRINTTS
|
||||
("frintts", Stable, &[]),
|
||||
// FEAT_HBC
|
||||
("hbc", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_I8MM
|
||||
("i8mm", Stable, &[]),
|
||||
// FEAT_JSCVT
|
||||
@ -131,6 +149,14 @@ pub fn is_stable(self) -> bool {
|
||||
("lor", Stable, &[]),
|
||||
// FEAT_LSE
|
||||
("lse", Stable, &[]),
|
||||
// FEAT_LSE128
|
||||
("lse128", Unstable(sym::aarch64_unstable_target_feature), &["lse"]),
|
||||
// FEAT_LSE2
|
||||
("lse2", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_LUT
|
||||
("lut", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_MOPS
|
||||
("mops", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_MTE & FEAT_MTE2
|
||||
("mte", Stable, &[]),
|
||||
// FEAT_AdvSimd & FEAT_FP
|
||||
@ -143,14 +169,16 @@ pub fn is_stable(self) -> bool {
|
||||
("pan", Stable, &[]),
|
||||
// FEAT_PMUv3
|
||||
("pmuv3", Stable, &[]),
|
||||
// FEAT_RAND
|
||||
// FEAT_RNG
|
||||
("rand", Stable, &[]),
|
||||
// FEAT_RAS & FEAT_RASv1p1
|
||||
("ras", Stable, &[]),
|
||||
// FEAT_RCPC
|
||||
// FEAT_LRCPC
|
||||
("rcpc", Stable, &[]),
|
||||
// FEAT_RCPC2
|
||||
// FEAT_LRCPC2
|
||||
("rcpc2", Stable, &["rcpc"]),
|
||||
// FEAT_LRCPC3
|
||||
("rcpc3", Unstable(sym::aarch64_unstable_target_feature), &["rcpc2"]),
|
||||
// FEAT_RDM
|
||||
("rdm", Stable, &["neon"]),
|
||||
// FEAT_SB
|
||||
@ -161,10 +189,36 @@ pub fn is_stable(self) -> bool {
|
||||
("sha3", Stable, &["sha2"]),
|
||||
// FEAT_SM3 & FEAT_SM4
|
||||
("sm4", Stable, &["neon"]),
|
||||
// FEAT_SME
|
||||
("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
|
||||
// FEAT_SME_F16F16
|
||||
("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
|
||||
// FEAT_SME_F64F64
|
||||
("sme-f64f64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
|
||||
// FEAT_SME_F8F16
|
||||
("sme-f8f16", Unstable(sym::aarch64_unstable_target_feature), &["sme-f8f32"]),
|
||||
// FEAT_SME_F8F32
|
||||
("sme-f8f32", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
|
||||
// FEAT_SME_FA64
|
||||
("sme-fa64", Unstable(sym::aarch64_unstable_target_feature), &["sme", "sve2"]),
|
||||
// FEAT_SME_I16I64
|
||||
("sme-i16i64", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
|
||||
// FEAT_SME_LUTv2
|
||||
("sme-lutv2", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// FEAT_SME2
|
||||
("sme2", Unstable(sym::aarch64_unstable_target_feature), &["sme"]),
|
||||
// FEAT_SME2p1
|
||||
("sme2p1", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
|
||||
// FEAT_SPE
|
||||
("spe", Stable, &[]),
|
||||
// FEAT_SSBS & FEAT_SSBS2
|
||||
("ssbs", Stable, &[]),
|
||||
// FEAT_SSVE_FP8FDOT2
|
||||
("ssve-fp8dot2", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8dot4"]),
|
||||
// FEAT_SSVE_FP8FDOT4
|
||||
("ssve-fp8dot4", Unstable(sym::aarch64_unstable_target_feature), &["ssve-fp8fma"]),
|
||||
// FEAT_SSVE_FP8FMA
|
||||
("ssve-fp8fma", Unstable(sym::aarch64_unstable_target_feature), &["sme2", "fp8"]),
|
||||
// FEAT_SVE
|
||||
// It was decided that SVE requires Neon: https://github.com/rust-lang/rust/pull/91608
|
||||
//
|
||||
@ -173,9 +227,11 @@ pub fn is_stable(self) -> bool {
|
||||
//
|
||||
// "For backwards compatibility, Neon and VFP are required in the latest architectures."
|
||||
("sve", Stable, &["neon"]),
|
||||
// FEAT_SVE_B16B16 (SVE or SME Instructions)
|
||||
("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
|
||||
// FEAT_SVE2
|
||||
("sve2", Stable, &["sve"]),
|
||||
// FEAT_SVE2_AES
|
||||
// FEAT_SVE_AES & FEAT_SVE_PMULL128
|
||||
("sve2-aes", Stable, &["sve2", "aes"]),
|
||||
// FEAT_SVE2_BitPerm
|
||||
("sve2-bitperm", Stable, &["sve2"]),
|
||||
@ -183,6 +239,8 @@ pub fn is_stable(self) -> bool {
|
||||
("sve2-sha3", Stable, &["sve2", "sha3"]),
|
||||
// FEAT_SVE2_SM4
|
||||
("sve2-sm4", Stable, &["sve2", "sm4"]),
|
||||
// FEAT_SVE2p1
|
||||
("sve2p1", Unstable(sym::aarch64_unstable_target_feature), &["sve2"]),
|
||||
// FEAT_TME
|
||||
("tme", Stable, &[]),
|
||||
(
|
||||
@ -199,9 +257,19 @@ pub fn is_stable(self) -> bool {
|
||||
("v8.4a", Unstable(sym::aarch64_ver_target_feature), &["v8.3a", "dotprod", "dit", "flagm"]),
|
||||
("v8.5a", Unstable(sym::aarch64_ver_target_feature), &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
|
||||
("v8.6a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "bf16", "i8mm"]),
|
||||
("v8.7a", Unstable(sym::aarch64_ver_target_feature), &[]),
|
||||
("v8.7a", Unstable(sym::aarch64_ver_target_feature), &["v8.6a", "wfxt"]),
|
||||
("v8.8a", Unstable(sym::aarch64_ver_target_feature), &["v8.7a", "hbc", "mops"]),
|
||||
("v8.9a", Unstable(sym::aarch64_ver_target_feature), &["v8.8a", "cssc"]),
|
||||
("v9.1a", Unstable(sym::aarch64_ver_target_feature), &["v9a", "v8.6a"]),
|
||||
("v9.2a", Unstable(sym::aarch64_ver_target_feature), &["v9.1a", "v8.7a"]),
|
||||
("v9.3a", Unstable(sym::aarch64_ver_target_feature), &["v9.2a", "v8.8a"]),
|
||||
("v9.4a", Unstable(sym::aarch64_ver_target_feature), &["v9.3a", "v8.9a"]),
|
||||
("v9.5a", Unstable(sym::aarch64_ver_target_feature), &["v9.4a"]),
|
||||
("v9a", Unstable(sym::aarch64_ver_target_feature), &["v8.5a", "sve2"]),
|
||||
// FEAT_VHE
|
||||
("vh", Stable, &[]),
|
||||
// FEAT_WFxT
|
||||
("wfxt", Unstable(sym::aarch64_unstable_target_feature), &[]),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
|
@ -4,6 +4,10 @@
|
||||
all(target_arch = "arm", any(target_os = "linux", target_os = "android")),
|
||||
feature(stdarch_arm_feature_detection)
|
||||
)]
|
||||
#![cfg_attr(
|
||||
all(target_arch = "aarch64", any(target_os = "linux", target_os = "android")),
|
||||
feature(stdarch_aarch64_feature_detection)
|
||||
)]
|
||||
#![cfg_attr(
|
||||
all(target_arch = "powerpc", target_os = "linux"),
|
||||
feature(stdarch_powerpc_feature_detection)
|
||||
@ -36,21 +40,34 @@ fn aarch64_linux() {
|
||||
println!("bf16: {}", is_aarch64_feature_detected!("bf16"));
|
||||
println!("bti: {}", is_aarch64_feature_detected!("bti"));
|
||||
println!("crc: {}", is_aarch64_feature_detected!("crc"));
|
||||
println!("cssc: {}", is_aarch64_feature_detected!("cssc"));
|
||||
println!("dit: {}", is_aarch64_feature_detected!("dit"));
|
||||
println!("dotprod: {}", is_aarch64_feature_detected!("dotprod"));
|
||||
println!("dpb2: {}", is_aarch64_feature_detected!("dpb2"));
|
||||
println!("dpb: {}", is_aarch64_feature_detected!("dpb"));
|
||||
println!("ecv: {}", is_aarch64_feature_detected!("ecv"));
|
||||
println!("f32mm: {}", is_aarch64_feature_detected!("f32mm"));
|
||||
println!("f64mm: {}", is_aarch64_feature_detected!("f64mm"));
|
||||
println!("faminmax: {}", is_aarch64_feature_detected!("faminmax"));
|
||||
println!("fcma: {}", is_aarch64_feature_detected!("fcma"));
|
||||
println!("fhm: {}", is_aarch64_feature_detected!("fhm"));
|
||||
println!("flagm2: {}", is_aarch64_feature_detected!("flagm2"));
|
||||
println!("flagm: {}", is_aarch64_feature_detected!("flagm"));
|
||||
println!("fp16: {}", is_aarch64_feature_detected!("fp16"));
|
||||
println!("fp8: {}", is_aarch64_feature_detected!("fp8"));
|
||||
println!("fp8dot2: {}", is_aarch64_feature_detected!("fp8dot2"));
|
||||
println!("fp8dot4: {}", is_aarch64_feature_detected!("fp8dot4"));
|
||||
println!("fp8fma: {}", is_aarch64_feature_detected!("fp8fma"));
|
||||
println!("fpmr: {}", is_aarch64_feature_detected!("fpmr"));
|
||||
println!("frintts: {}", is_aarch64_feature_detected!("frintts"));
|
||||
println!("hbc: {}", is_aarch64_feature_detected!("hbc"));
|
||||
println!("i8mm: {}", is_aarch64_feature_detected!("i8mm"));
|
||||
println!("jsconv: {}", is_aarch64_feature_detected!("jsconv"));
|
||||
println!("lse128: {}", is_aarch64_feature_detected!("lse128"));
|
||||
println!("lse2: {}", is_aarch64_feature_detected!("lse2"));
|
||||
println!("lse: {}", is_aarch64_feature_detected!("lse"));
|
||||
println!("lut: {}", is_aarch64_feature_detected!("lut"));
|
||||
println!("mops: {}", is_aarch64_feature_detected!("mops"));
|
||||
println!("mte: {}", is_aarch64_feature_detected!("mte"));
|
||||
println!("neon: {}", is_aarch64_feature_detected!("neon"));
|
||||
println!("paca: {}", is_aarch64_feature_detected!("paca"));
|
||||
@ -58,20 +75,37 @@ fn aarch64_linux() {
|
||||
println!("pmull: {}", is_aarch64_feature_detected!("pmull"));
|
||||
println!("rand: {}", is_aarch64_feature_detected!("rand"));
|
||||
println!("rcpc2: {}", is_aarch64_feature_detected!("rcpc2"));
|
||||
println!("rcpc3: {}", is_aarch64_feature_detected!("rcpc3"));
|
||||
println!("rcpc: {}", is_aarch64_feature_detected!("rcpc"));
|
||||
println!("rdm: {}", is_aarch64_feature_detected!("rdm"));
|
||||
println!("sb: {}", is_aarch64_feature_detected!("sb"));
|
||||
println!("sha2: {}", is_aarch64_feature_detected!("sha2"));
|
||||
println!("sha3: {}", is_aarch64_feature_detected!("sha3"));
|
||||
println!("sm4: {}", is_aarch64_feature_detected!("sm4"));
|
||||
println!("sme-f16f16: {}", is_aarch64_feature_detected!("sme-f16f16"));
|
||||
println!("sme-f64f64: {}", is_aarch64_feature_detected!("sme-f64f64"));
|
||||
println!("sme-f8f16: {}", is_aarch64_feature_detected!("sme-f8f16"));
|
||||
println!("sme-f8f32: {}", is_aarch64_feature_detected!("sme-f8f32"));
|
||||
println!("sme-fa64: {}", is_aarch64_feature_detected!("sme-fa64"));
|
||||
println!("sme-i16i64: {}", is_aarch64_feature_detected!("sme-i16i64"));
|
||||
println!("sme-lutv2: {}", is_aarch64_feature_detected!("sme-lutv2"));
|
||||
println!("sme2: {}", is_aarch64_feature_detected!("sme2"));
|
||||
println!("sme2p1: {}", is_aarch64_feature_detected!("sme2p1"));
|
||||
println!("sme: {}", is_aarch64_feature_detected!("sme"));
|
||||
println!("ssbs: {}", is_aarch64_feature_detected!("ssbs"));
|
||||
println!("ssve-fp8dot2: {}", is_aarch64_feature_detected!("ssve-fp8dot2"));
|
||||
println!("ssve-fp8dot4: {}", is_aarch64_feature_detected!("ssve-fp8dot4"));
|
||||
println!("ssve-fp8fma: {}", is_aarch64_feature_detected!("ssve-fp8fma"));
|
||||
println!("sve-b16b16: {}", is_aarch64_feature_detected!("sve-b16b16"));
|
||||
println!("sve2-aes: {}", is_aarch64_feature_detected!("sve2-aes"));
|
||||
println!("sve2-bitperm: {}", is_aarch64_feature_detected!("sve2-bitperm"));
|
||||
println!("sve2-sha3: {}", is_aarch64_feature_detected!("sve2-sha3"));
|
||||
println!("sve2-sm4: {}", is_aarch64_feature_detected!("sve2-sm4"));
|
||||
println!("sve2: {}", is_aarch64_feature_detected!("sve2"));
|
||||
println!("sve2p1: {}", is_aarch64_feature_detected!("sve2p1"));
|
||||
println!("sve: {}", is_aarch64_feature_detected!("sve"));
|
||||
println!("tme: {}", is_aarch64_feature_detected!("tme"));
|
||||
println!("wfxt: {}", is_aarch64_feature_detected!("wfxt"));
|
||||
// tidy-alphabetical-end
|
||||
}
|
||||
|
||||
|
@ -3,21 +3,21 @@
|
||||
//@ compile-flags: --crate-type=rlib --target=aarch64-unknown-linux-gnu
|
||||
//@ needs-llvm-components: aarch64
|
||||
|
||||
// The "+v8a" feature is matched as optional as it isn't added when we
|
||||
// are targeting older LLVM versions. Once the min supported version
|
||||
// is LLVM-14 we can remove the optional regex matching for this feature.
|
||||
// The "+fpmr" feature is matched as optional as it is only an explicit
|
||||
// feature in LLVM 18. Once the min supported version is LLVM-19 the optional
|
||||
// regex matching for this feature can be removed.
|
||||
|
||||
//@ [ENABLE_SVE] compile-flags: -C target-feature=+sve -Copt-level=0
|
||||
// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
|
||||
// ENABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+sve,?)|(\+neon,?)|(\+fp-armv8,?))*}}" }
|
||||
|
||||
//@ [DISABLE_SVE] compile-flags: -C target-feature=-sve -Copt-level=0
|
||||
// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-sve,?)|(\+neon,?))*}}" }
|
||||
// DISABLE_SVE: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-sve,?)|(\+neon,?))*}}" }
|
||||
|
||||
//@ [DISABLE_NEON] compile-flags: -C target-feature=-neon -Copt-level=0
|
||||
// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
|
||||
// DISABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(-fp-armv8,?)|(-neon,?))*}}" }
|
||||
|
||||
//@ [ENABLE_NEON] compile-flags: -C target-feature=+neon -Copt-level=0
|
||||
// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
|
||||
// ENABLE_NEON: attributes #0 = { {{.*}} "target-features"="{{((\+outline-atomics,?)|(\+v8a,?)|(\+fpmr,?)?|(\+fp-armv8,?)|(\+neon,?))*}}" }
|
||||
|
||||
#![feature(no_core, lang_items)]
|
||||
#![no_core]
|
||||
|
@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra`
|
||||
LL | cfg!(target_feature = "zebra");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 201 more
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, and `avx512vpopcntdq` and 239 more
|
||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
|
||||
|
||||
warning: 27 warnings emitted
|
||||
|
@ -165,7 +165,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
||||
LL | target_feature = "_UNEXPECTED_VALUE",
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt`
|
||||
= note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `amx-bf16`, `amx-complex`, `amx-fp16`, `amx-int8`, `amx-tile`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `avxifma`, `avxneconvert`, `avxvnni`, `avxvnniint16`, `avxvnniint8`, `backchain`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `cssc`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `ecv`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `faminmax`, `fcma`, `fdivdu`, `fhm`, `flagm`, `flagm2`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fp8`, `fp8dot2`, `fp8dot4`, `fp8fma`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `hbc`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lse128`, `lse2`, `lsx`, `lut`, `lvz`, `lzcnt`, `m`, `mclass`, `mops`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rcpc3`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sha512`, `sign-ext`, `simd128`, `sm3`, `sm4`, `sme`, `sme-f16f16`, `sme-f64f64`, `sme-f8f16`, `sme-f8f32`, `sme-fa64`, `sme-i16i64`, `sme-lutv2`, `sme2`, `sme2p1`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `ssve-fp8dot2`, `ssve-fp8dot4`, `ssve-fp8fma`, `sve`, `sve-b16b16`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `sve2p1`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `v8.8a`, `v8.9a`, `v9.1a`, `v9.2a`, `v9.3a`, `v9.4a`, `v9.5a`, `v9a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vector`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `wfxt`, `xop`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt`
|
||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
|
||||
|
||||
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
||||
|
@ -17,6 +17,7 @@
|
||||
// gate-test-ermsb_target_feature
|
||||
// gate-test-bpf_target_feature
|
||||
// gate-test-aarch64_ver_target_feature
|
||||
// gate-test-aarch64_unstable_target_feature
|
||||
// gate-test-csky_target_feature
|
||||
// gate-test-loongarch_target_feature
|
||||
// gate-test-lahfsahf_target_feature
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: the target feature `avx512bw` is currently unstable
|
||||
--> $DIR/gate.rs:26:18
|
||||
--> $DIR/gate.rs:27:18
|
||||
|
|
||||
LL | #[target_feature(enable = "avx512bw")]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user