Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/intrinsic-test/src/arm/json_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ fn json_to_intrinsic(
arguments,
results: result_ty,
arch_tags: intr.architectures,
extension: intr.simd_isa,
})
}

Expand Down
59 changes: 58 additions & 1 deletion crates/intrinsic-test/src/arm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod types;
use crate::common::SupportedArchitectureTest;
use crate::common::cli::{CcArgStyle, ProcessedCli};
use crate::common::intrinsic::Intrinsic;
use crate::common::intrinsic_helpers::TypeKind;
use crate::common::intrinsic_helpers::{SimdLen, TypeKind};
use intrinsic::ArmIntrinsicType;
use json_parser::get_neon_intrinsics;

Expand All @@ -32,11 +32,13 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
// GCC uses an extra `-` in the arch name
match cli_options.cc_arg_style {
CcArgStyle::Clang => vec!["-march=armv8.6a+crypto+crc+dotprod+fp16"],
// SVE tests aren't run under GCC so there are no target features added for SVE
CcArgStyle::Gcc => vec!["-march=armv8.6-a+crypto+crc+dotprod+fp16+sha3+sm4"],
}
}

fn create(cli_options: &ProcessedCli) -> Self {
let big_endian = cli_options.target.starts_with("aarch64_be");
let a32 = cli_options.target.starts_with("armv7");
let mut intrinsics =
get_neon_intrinsics(&cli_options.filename).expect("Error parsing input file");
Expand All @@ -54,6 +56,53 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
// Skip bfloat intrinsics - not currently supported
.filter(|i| i.results.kind() != TypeKind::BFloat)
.filter(|i| !i.arguments.iter().any(|a| a.ty.kind() == TypeKind::BFloat))
// Skip SVE intrinsics that have `f16` - not yet implemented!
.filter(|i| {
let has_f16_arg = i
.arguments
.iter()
.any(|a| a.ty.kind() == TypeKind::Float && a.ty.bit_len == Some(16));
let has_sve_arg = i
.arguments
.iter()
.any(|a| a.ty.simd_len == Some(SimdLen::Scalable));
!(has_f16_arg && has_sve_arg)
})
.filter(|i| {
let has_f16_ret =
i.results.kind() == TypeKind::Float && i.results.bit_len == Some(16);
let has_sve_ret = i.results.simd_len == Some(SimdLen::Scalable);
!(has_f16_ret && has_sve_ret)
})
// Skip `svqcvtn{u,}n*_x2` intrinsics - not yet implemented!
.filter(|i| !(i.name.starts_with("svqcvtn") && i.name.ends_with("_x2")))
// Skip `svqrshr{u,}n*_x2` intrinsics - not yet implemented!
.filter(|i| !(i.name.starts_with("svqrshrn") && i.name.ends_with("_x2")))
.filter(|i| !(i.name.starts_with("svqrshrun") && i.name.ends_with("_x2")))
// Skip `svclamp*` intrinsics - not yet implemented!
.filter(|i| !i.name.starts_with("svclamp"))
// Skip `svdot{_lane,}_{s,u}32_{s,u}16` intrinsics - not yet implemented!
.filter(|i| {
i.name != "svdot_lane_u32_u16"
&& i.name != "svdot_lane_s32_s16"
&& i.name != "svdot_u32_u16"
&& i.name != "svdot_s32_s16"
})
// Skip `svrevd*` intrinsics - not yet implemented!
.filter(|i| !i.name.starts_with("svrevd"))
// Skip `svpsel_lane_b*` intrinsics - not yet implemented!
.filter(|i| !i.name.starts_with("svpsel_lane_b"))
// Skip `svundef*` intrinsics - to avoid undefined behaviour in Rust, these return
// zeroed vectors in Rust, which are inherently going to be different than the
// undefined vectors returned by the C intrinsics.
.filter(|i| !i.name.starts_with("svundef"))
// Skip `sveorv` intrinsics - the code produced by `intrinsic-test` for these
// miscompiles and the Rust intrinsic call gets replaced by a constant zero (see
// llvm/llvm-project#203921).
.filter(|i| !i.name.starts_with("sveorv"))
// These load intrinsics expect each element in the scalable vector `bases` argument to
// be able to be cast to a pointer, which we don't support generating tests for yet.
.filter(|i| !(i.name.starts_with("svld") && i.name.contains("_gather_")))
// Skip pointers for now, we would probably need to look at the return
// type to work out how many elements we need to point to.
.filter(|i| !i.arguments.iter().any(|a| a.is_ptr()))
Expand All @@ -63,6 +112,14 @@ impl SupportedArchitectureTest for ArmArchitectureTest {
.filter(|i| !cli_options.skip.contains(&i.name))
// Skip A64-specific intrinsics on A32
.filter(|i| !(a32 && i.arch_tags == vec!["A64".to_string()]))
// Skip SVE intrinsics on big endian
.filter(|i| !(big_endian && (i.extension == "SVE" || i.extension == "SVE2")))
// Skip SVE intrinsics when testing against GCC as our wrappers run into ICEs
// See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125818>
.filter(|i| {
!(matches!(cli_options.cc_arg_style, CcArgStyle::Gcc)
&& (i.extension == "SVE" || i.extension == "SVE2"))
})
.take(sample_size)
.collect::<Vec<_>>();

Expand Down
3 changes: 3 additions & 0 deletions crates/intrinsic-test/src/common/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ pub struct Intrinsic<T: IntrinsicTypeDefinition> {

/// Any architecture-specific tags.
pub arch_tags: Vec<String>,

/// Specific extension that the intrinsic is from
pub extension: String,
}

/// Invokes `f` for each combination of the values in the constraint ranges.
Expand Down
1 change: 1 addition & 0 deletions crates/intrinsic-test/src/x86/xml_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,5 +145,6 @@ fn xml_to_intrinsic(
arguments,
results: result.unwrap(),
arch_tags: intr.cpuid,
extension: intr.tech,
})
}