Verify that all intrinsics have a run-time test

This commit is contained in:
gnzlbg 2019-08-17 21:14:54 +02:00
parent 4645479b83
commit ed67655cc8
6 changed files with 366 additions and 6 deletions

View file

@ -3437,7 +3437,7 @@ mod tests {
}
#[simd_test(enable = "sse")]
pub unsafe fn test_mm_cvtsi32_ss() {
unsafe fn test_mm_cvtsi32_ss() {
let inputs = &[
(4555i32, 4555.0f32),
(322223333, 322223330.0),
@ -3455,7 +3455,7 @@ mod tests {
}
#[simd_test(enable = "sse")]
pub unsafe fn test_mm_cvtss_f32() {
unsafe fn test_mm_cvtss_f32() {
let a = _mm_setr_ps(312.0134, 5.0, 6.0, 7.0);
assert_eq!(_mm_cvtss_f32(a), 312.0134);
}

View file

@ -128,7 +128,7 @@ mod tests {
}
#[simd_test(enable = "sse")]
pub unsafe fn test_mm_cvtsi64_ss() {
unsafe fn test_mm_cvtsi64_ss() {
let inputs = &[
(4555i64, 4555.0f32),
(322223333, 322223330.0),

View file

@ -37,14 +37,33 @@ fn functions(input: TokenStream, dirs: &[&str]) -> TokenStream {
let mut functions = Vec::new();
for &mut (ref mut file, ref path) in &mut files {
for item in file.items.drain(..) {
if let syn::Item::Fn(f) = item {
functions.push((f, path))
for mut item in file.items.drain(..) {
match item {
syn::Item::Fn(f) => functions.push((f, path)),
syn::Item::Mod(ref mut m) => {
if let Some(ref mut m) = m.content {
for i in m.1.drain(..) {
if let syn::Item::Fn(f) = i {
functions.push((f, path))
}
}
}
}
_ => (),
}
}
}
assert!(!functions.is_empty());
let mut tests = std::collections::HashSet::<String>::new();
for f in &functions {
let id = format!("{}", f.0.ident);
if id.starts_with("test_") {
tests.insert(id);
}
}
assert!(!tests.is_empty());
functions.retain(|&(ref f, _)| {
if let syn::Visibility::Public(_) = f.vis {
if f.unsafety.is_some() {
@ -84,6 +103,16 @@ fn functions(input: TokenStream, dirs: &[&str]) -> TokenStream {
quote! { None }
};
let required_const = find_required_const(&f.attrs);
// strip leading underscore from fn name when building a test
// _mm_foo -> mm_foo such that the test name is test_mm_foo.
let test_name_string = format!("{}", name);
let mut test_name_id = test_name_string.as_str();
while test_name_id.starts_with('_') {
test_name_id = &test_name_id[1..];
}
let has_test = tests.contains(&format!("test_{}", test_name_id));
quote! {
Function {
name: stringify!(#name),
@ -93,6 +122,7 @@ fn functions(input: TokenStream, dirs: &[&str]) -> TokenStream {
instrs: &[#(#instrs),*],
file: stringify!(#path),
required_const: &[#(#required_const),*],
has_test: #has_test,
}
}
})

View file

@ -18,6 +18,7 @@ struct Function {
instrs: &'static [&'static str],
file: &'static str,
required_const: &'static [usize],
has_test: bool,
}
static F16: Type = Type::PrimFloat(16);
@ -197,6 +198,155 @@ fn verify_all_signatures() {
let mut all_valid = true;
'outer: for rust in FUNCTIONS {
if !rust.has_test {
let skip = [
"vaddq_s64",
"vaddq_u64",
"vrsqrte_f32",
"vtbl1_s8",
"vtbl1_u8",
"vtbl1_p8",
"vtbl2_s8",
"vtbl2_u8",
"vtbl2_p8",
"vtbl3_s8",
"vtbl3_u8",
"vtbl3_p8",
"vtbl4_s8",
"vtbl4_u8",
"vtbl4_p8",
"vtbx1_s8",
"vtbx1_u8",
"vtbx1_p8",
"vtbx2_s8",
"vtbx2_u8",
"vtbx2_p8",
"vtbx3_s8",
"vtbx3_u8",
"vtbx3_p8",
"vtbx4_s8",
"vtbx4_u8",
"vtbx4_p8",
"udf",
"_clz_u8",
"_clz_u16",
"_clz_u32",
"_rbit_u32",
"_rev_u16",
"_rev_u32",
"__breakpoint",
"vpminq_f32",
"vpminq_f64",
"vpmaxq_f32",
"vpmaxq_f64",
"vcombine_s8",
"vcombine_s16",
"vcombine_s32",
"vcombine_s64",
"vcombine_u8",
"vcombine_u16",
"vcombine_u32",
"vcombine_u64",
"vcombine_p64",
"vcombine_f32",
"vcombine_p8",
"vcombine_p16",
"vcombine_f64",
"vtbl1_s8",
"vtbl1_u8",
"vtbl1_p8",
"vtbl2_s8",
"vtbl2_u8",
"vtbl2_p8",
"vtbl3_s8",
"vtbl3_u8",
"vtbl3_p8",
"vtbl4_s8",
"vtbl4_u8",
"vtbl4_p8",
"vtbx1_s8",
"vtbx1_u8",
"vtbx1_p8",
"vtbx2_s8",
"vtbx2_u8",
"vtbx2_p8",
"vtbx3_s8",
"vtbx3_u8",
"vtbx3_p8",
"vtbx4_s8",
"vtbx4_u8",
"vtbx4_p8",
"vqtbl1_s8",
"vqtbl1q_s8",
"vqtbl1_u8",
"vqtbl1q_u8",
"vqtbl1_p8",
"vqtbl1q_p8",
"vqtbx1_s8",
"vqtbx1q_s8",
"vqtbx1_u8",
"vqtbx1q_u8",
"vqtbx1_p8",
"vqtbx1q_p8",
"vqtbl2_s8",
"vqtbl2q_s8",
"vqtbl2_u8",
"vqtbl2q_u8",
"vqtbl2_p8",
"vqtbl2q_p8",
"vqtbx2_s8",
"vqtbx2q_s8",
"vqtbx2_u8",
"vqtbx2q_u8",
"vqtbx2_p8",
"vqtbx2q_p8",
"vqtbl3_s8",
"vqtbl3q_s8",
"vqtbl3_u8",
"vqtbl3q_u8",
"vqtbl3_p8",
"vqtbl3q_p8",
"vqtbx3_s8",
"vqtbx3q_s8",
"vqtbx3_u8",
"vqtbx3q_u8",
"vqtbx3_p8",
"vqtbx3q_p8",
"vqtbl4_s8",
"vqtbl4q_s8",
"vqtbl4_u8",
"vqtbl4q_u8",
"vqtbl4_p8",
"vqtbl4q_p8",
"vqtbx4_s8",
"vqtbx4q_s8",
"vqtbx4_u8",
"vqtbx4q_u8",
"vqtbx4_p8",
"vqtbx4q_p8",
"brk",
"_rev_u64",
"_clz_u64",
"_rbit_u64",
"_cls_u32",
"_cls_u64",
];
if !skip.contains(&rust.name) {
println!(
"missing run-time test named `test_{}` for `{}`",
{
let mut id = rust.name;
while id.starts_with('_') {
id = &id[1..];
}
id
},
rust.name
);
all_valid = false;
}
}
// Skip some intrinsics that aren't NEON and are located in different
// places than the whitelists below.
match rust.name {

View file

@ -16,6 +16,7 @@ struct Function {
instrs: &'static [&'static str],
file: &'static str,
required_const: &'static [usize],
has_test: bool,
}
static F16: Type = Type::PrimFloat(16);
@ -200,6 +201,34 @@ fn verify_all_signatures() {
let mut all_valid = true;
for rust in FUNCTIONS {
if !rust.has_test {
let skip = [
"__msa_ceqi_d",
"__msa_cfcmsa",
"__msa_clei_s_d",
"__msa_clti_s_d",
"__msa_ctcmsa",
"__msa_ldi_d",
"__msa_maxi_s_d",
"__msa_mini_s_d",
"break_",
];
if !skip.contains(&rust.name) {
println!(
"missing run-time test named `test_{}` for `{}`",
{
let mut id = rust.name;
while id.starts_with('_') {
id = &id[1..];
}
id
},
rust.name
);
all_valid = false;
}
}
// Skip some intrinsics that aren't part of MSA
match rust.name {
"break_" => continue,

View file

@ -27,6 +27,7 @@ struct Function {
instrs: &'static [&'static str],
file: &'static str,
required_const: &'static [usize],
has_test: bool,
}
static F32: Type = Type::PrimFloat(32);
@ -140,6 +141,156 @@ fn verify_all_signatures() {
let mut all_valid = true;
'outer: for rust in FUNCTIONS {
if !rust.has_test {
// FIXME: this list should be almost empty
let skip = [
"__readeflags",
"__readeflags",
"__writeeflags",
"__writeeflags",
"_mm_comige_ss",
"_mm_cvt_ss2si",
"_mm_cvtt_ss2si",
"_mm_cvt_si2ss",
"_mm_set_ps1",
"_mm_load_ps1",
"_mm_store_ps1",
"_mm_getcsr",
"_mm_setcsr",
"_MM_GET_EXCEPTION_MASK",
"_MM_GET_EXCEPTION_STATE",
"_MM_GET_FLUSH_ZERO_MODE",
"_MM_GET_ROUNDING_MODE",
"_MM_SET_EXCEPTION_MASK",
"_MM_SET_EXCEPTION_STATE",
"_MM_SET_FLUSH_ZERO_MODE",
"_MM_SET_ROUNDING_MODE",
"_mm_prefetch",
"_mm_undefined_ps",
"_m_pmaxsw",
"_m_pmaxub",
"_m_pminsw",
"_m_pminub",
"_m_pavgb",
"_m_pavgw",
"_m_psadbw",
"_mm_cvt_pi2ps",
"_m_maskmovq",
"_m_pextrw",
"_m_pinsrw",
"_m_pmovmskb",
"_m_pshufw",
"_mm_cvtt_ps2pi",
"_mm_cvt_ps2pi",
"__cpuid_count",
"__cpuid",
"__get_cpuid_max",
"_xsave",
"_xrstor",
"_xsetbv",
"_xgetbv",
"_xsaveopt",
"_xsavec",
"_xsaves",
"_xrstors",
"_mm_bslli_si128",
"_mm_bsrli_si128",
"_mm_undefined_pd",
"_mm_undefined_si128",
"_mm_cvtps_ph",
"_mm256_cvtps_ph",
"_rdtsc",
"__rdtscp",
"_mm256_castps128_ps256",
"_mm256_castpd128_pd256",
"_mm256_castsi128_si256",
"_mm256_undefined_ps",
"_mm256_undefined_pd",
"_mm256_undefined_si256",
"_bextr2_u32",
"_mm_tzcnt_32",
"_mm512_setzero_si512",
"_mm512_setr_epi32",
"_mm512_set1_epi64",
"_m_paddb",
"_m_paddw",
"_m_paddd",
"_m_paddsb",
"_m_paddsw",
"_m_paddusb",
"_m_paddusw",
"_m_psubb",
"_m_psubw",
"_m_psubd",
"_m_psubsb",
"_m_psubsw",
"_m_psubusb",
"_m_psubusw",
"_mm_set_pi16",
"_mm_set_pi32",
"_mm_set_pi8",
"_mm_set1_pi16",
"_mm_set1_pi32",
"_mm_set1_pi8",
"_mm_setr_pi16",
"_mm_setr_pi32",
"_mm_setr_pi8",
"ud2",
"_mm_min_epi8",
"_mm_min_epi32",
"_xbegin",
"_xend",
"_rdrand16_step",
"_rdrand32_step",
"_rdseed16_step",
"_rdseed32_step",
"_fxsave",
"_fxrstor",
"_t1mskc_u64",
"_mm256_shuffle_epi32",
"_mm256_bslli_epi128",
"_mm256_bsrli_epi128",
"_mm256_unpackhi_epi8",
"_mm256_unpacklo_epi8",
"_mm256_unpackhi_epi16",
"_mm256_unpacklo_epi16",
"_mm256_unpackhi_epi32",
"_mm256_unpacklo_epi32",
"_mm256_unpackhi_epi64",
"_mm256_unpacklo_epi64",
"_xsave64",
"_xrstor64",
"_xsaveopt64",
"_xsavec64",
"_xsaves64",
"_xrstors64",
"_mm_cvtsi64x_si128",
"_mm_cvtsi128_si64x",
"_mm_cvtsi64x_sd",
"cmpxchg16b",
"_rdrand64_step",
"_rdseed64_step",
"_bextr2_u64",
"_mm_tzcnt_64",
"_fxsave64",
"_fxrstor64",
];
if !skip.contains(&rust.name) {
println!(
"missing run-time test named `test_{}` for `{}`",
{
let mut id = rust.name;
while id.starts_with('_') {
id = &id[1..];
}
id
},
rust.name
);
all_valid = false;
}
}
match rust.name {
// These aren't defined by Intel but they're defined by what appears
// to be all other compilers. For more information see