Skip to content

Commit f44dd5b

Browse files
committed
Simplify scalable vector testing
1 parent 77c0c7b commit f44dd5b

2 files changed

Lines changed: 94 additions & 117 deletions

File tree

crates/intrinsic-test/src/arm/mod.rs

Lines changed: 78 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -233,72 +233,91 @@ const fn svprfop_from_i32(value: i32) -> svprfop {
233233
}
234234
}
235235
236-
macro_rules! debug_print_integral {
237-
($($name:ident => ($ty:ty, $svptrue_fn:ident, $svcnt_fn:ident, $svst_fn:ident)),*) => {
238-
$(
239-
#[inline]
240-
#[target_feature(enable = "sve")]
241-
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
242-
pub fn $name(v: $ty) -> String {
243-
unsafe {
244-
let __pred = $svptrue_fn();
245-
let __num_elems = $svcnt_fn() as usize;
246-
let mut __buf = std::vec::Vec::with_capacity(__num_elems);
247-
$svst_fn(__pred, __buf.as_mut_ptr(), v);
248-
__buf.set_len(__num_elems);
249-
format!(
250-
"[{}]",
251-
__buf.iter().map(|el| el.to_string()).collect::<Vec<_>>().join(", ")
252-
)
253-
}
254-
}
255-
)*
236+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
237+
fn svint8_to_slice(a: &svint8_t) -> &[i8] {
238+
unsafe {
239+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntb() as usize)
256240
}
257241
}
258242
259-
debug_print_integral! {
260-
debug_print_f32 => (svfloat32_t, svptrue_b32, svcntw, svst1_f32),
261-
debug_print_f64 => (svfloat64_t, svptrue_b64, svcntd, svst1_f64),
262-
debug_print_s8 => (svint8_t, svptrue_b8, svcntb, svst1_s8),
263-
debug_print_s16 => (svint16_t, svptrue_b16, svcnth, svst1_s16),
264-
debug_print_s32 => (svint32_t, svptrue_b32, svcntw, svst1_s32),
265-
debug_print_s64 => (svint64_t, svptrue_b64, svcntd, svst1_s64),
266-
debug_print_u8 => (svuint8_t, svptrue_b8, svcntb, svst1_u8),
267-
debug_print_u16 => (svuint16_t, svptrue_b16, svcnth, svst1_u16),
268-
debug_print_u32 => (svuint32_t, svptrue_b32, svcntw, svst1_u32),
269-
debug_print_u64 => (svuint64_t, svptrue_b64, svcntd, svst1_u64)
243+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
244+
fn svuint8_to_slice(a: &svuint8_t) -> &[u8] {
245+
unsafe {
246+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntb() as usize)
247+
}
270248
}
271249
272-
macro_rules! debug_print_bool {
273-
($($name:ident => ($ty:ty, $svst_fn:ident, $svdup_fn:ident)),*) => {
274-
$(
275-
#[inline]
276-
#[target_feature(enable = "sve")]
277-
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
278-
pub fn $name(v: $ty) -> String {
279-
unsafe {
280-
let __num_elems = svcntb() as usize;
281-
let mut __buf = std::vec::Vec::with_capacity(__num_elems);
282-
$svst_fn(v, __buf.as_mut_ptr(), $svdup_fn(1));
283-
__buf.set_len(__num_elems);
284-
format!(
285-
"[{}]",
286-
__buf.iter()
287-
.map(|el| *el == 1)
288-
.map(|el| el.to_string())
289-
.collect::<Vec<_>>()
290-
.join(", ")
291-
)
292-
}
293-
}
294-
)*
250+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
251+
fn svint16_to_slice(a: &svint16_t) -> &[i16] {
252+
unsafe {
253+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcnth() as usize)
295254
}
296255
}
297256
298-
debug_print_bool! {
299-
debug_print_b8 => (svbool_t, svst1_u8, svdup_n_u8),
300-
debug_print_b16 => (svbool_t, svst1_u16, svdup_n_u16),
301-
debug_print_b32 => (svbool_t, svst1_u32, svdup_n_u32),
302-
debug_print_b64 => (svbool_t, svst1_u64, svdup_n_u64)
257+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
258+
fn svuint16_to_slice(a: &svuint16_t) -> &[u16] {
259+
unsafe {
260+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcnth() as usize)
261+
}
303262
}
263+
264+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
265+
fn svint32_to_slice(a: &svint32_t) -> &[i32] {
266+
unsafe {
267+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntw() as usize)
268+
}
269+
}
270+
271+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
272+
fn svuint32_to_slice(a: &svuint32_t) -> &[u32] {
273+
unsafe {
274+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntw() as usize)
275+
}
276+
}
277+
278+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
279+
fn svint64_to_slice(a: &svint64_t) -> &[i64] {
280+
unsafe {
281+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntd() as usize)
282+
}
283+
}
284+
285+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
286+
fn svuint64_to_slice(a: &svuint64_t) -> &[u64] {
287+
unsafe {
288+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntd() as usize)
289+
}
290+
}
291+
292+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
293+
fn svfloat32_to_slice(a: &svfloat32_t) -> &[NanEqF32] {
294+
unsafe {
295+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntw() as usize)
296+
}
297+
}
298+
299+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
300+
fn svfloat64_to_slice(a: &svfloat64_t) -> &[NanEqF64] {
301+
unsafe {
302+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntd() as usize)
303+
}
304+
}
305+
306+
#[repr(transparent)]
307+
#[derive(Copy,Clone,PartialEq,Eq)]
308+
struct b8(u8);
309+
310+
impl std::fmt::Debug for b8 {
311+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
312+
write!(f, "{:08b}", self.0)
313+
}
314+
}
315+
316+
#[cfg(all(any(target_arch = "aarch64", target_arch = "arm64ec"), target_endian = "little"))]
317+
fn svbool_to_slice(a: &svbool_t) -> &[b8] {
318+
unsafe {
319+
core::slice::from_raw_parts(core::ptr::from_ref(a).cast(), svcntd() as usize)
320+
}
321+
}
322+
304323
"#;

crates/intrinsic-test/src/arm/types.rs

Lines changed: 16 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use super::intrinsic::ArmType;
2-
use crate::common::PREDICATE_LOCAL;
32
use crate::common::intrinsic_helpers::{
43
IntrinsicType, Sign, SimdLen, TypeDefinition, TypeKind, default_fixed_vector_comparison,
54
};
@@ -114,17 +113,6 @@ impl TypeDefinition for ArmType {
114113
return default_fixed_vector_comparison(self, num_lanes);
115114
}
116115

117-
if self.kind() == TypeKind::Bool {
118-
// There isn't a `svcmpeq` for `svbool_t` and there aren't `svboolxN_t` types, so just
119-
// do an XOR and test it is empty.
120-
return format!(
121-
r#"
122-
let __eq = sveor_b_z({PREDICATE_LOCAL}, __rust_return_value, __c_return_value);
123-
assert!(!svptest_any({PREDICATE_LOCAL}, __eq), "{{}}", id);
124-
"#
125-
);
126-
}
127-
128116
// Returns `of` when `num_vectors == 1` otherwise returns the appropriate `svget` invocation
129117
// for `of`.
130118
let get = |num_vectors: u32, idx: u32, from: &'static str| -> String {
@@ -139,56 +127,26 @@ assert!(!svptest_any({PREDICATE_LOCAL}, __eq), "{{}}", id);
139127
)
140128
};
141129

130+
let prefix = match self.kind {
131+
TypeKind::Bool => "svbool".to_owned(),
132+
kind => format!("sv{}{}", kind.c_prefix(), self.inner_size()),
133+
};
134+
142135
let n = self.num_vectors();
143136
(0..n)
144137
.format_with("\n", |i, fmt| {
145-
match self.kind() {
146-
TypeKind::Float | TypeKind::BFloat => {
147-
// Floats need special handling because `NaN != NaN` normally - this
148-
// effectively does `(rust == c) || (isnan(rust) && isnan(c))`
149-
fmt(&format_args!(
150-
r#"
151-
let __rust_eq_return_value = {rust_return_value};
152-
let __c_eq_return_value = {c_return_value};
153-
let __eq_sans_nan = svcmpeq_{ty}{bl}({PREDICATE_LOCAL}, __rust_eq_return_value, __c_eq_return_value);
154-
let __rust_nan = svcmpuo_{ty}{bl}({PREDICATE_LOCAL}, __rust_eq_return_value, __rust_eq_return_value);
155-
let __c_nan = svcmpuo_{ty}{bl}({PREDICATE_LOCAL}, __c_eq_return_value, __c_eq_return_value);
156-
let __both_nan = svand_b_z({PREDICATE_LOCAL}, __rust_nan, __c_nan);
157-
let __eq = svorr_b_z({PREDICATE_LOCAL}, __eq_sans_nan, __both_nan);
158-
if !svptest_any(__pred, __eq) {{
159-
let __rust_pretty = debug_print_{ty}{bl}(__rust_eq_return_value);
160-
let __c_pretty = debug_print_{ty}{bl}(__c_eq_return_value);
161-
panic!("{{}}-{i_plus_one}/{n}\nRust: {{__rust_pretty}}\nC: {{__c_pretty}}", id);
162-
}}
163-
"#,
164-
ty = self.rust_intrinsic_name_prefix(),
165-
bl = self.inner_size(),
166-
rust_return_value = get(n, i, "__rust_return_value"),
167-
c_return_value = get(n, i, "__c_return_value"),
168-
i_plus_one = i + 1, // so that the output is "1/2" and "2/2"
169-
))
170-
}
171-
_ => {
172-
// Most types can just use `svcmpeq`
173-
fmt(&format_args!(
174-
r#"
175-
let __rust_eq_return_value = {rust_return_value};
176-
let __c_eq_return_value = {c_return_value};
177-
let __eq = svcmpeq_{ty}{bl}({PREDICATE_LOCAL}, __rust_eq_return_value, __c_eq_return_value);
178-
if !svptest_any(__pred, __eq) {{
179-
let __rust_pretty = debug_print_{ty}{bl}(__rust_eq_return_value);
180-
let __c_pretty = debug_print_{ty}{bl}(__c_eq_return_value);
181-
panic!("{{}}-{i_plus_one}/{n}\nRust: {{__rust_pretty}}\nC: {{__c_pretty}}", id);
182-
}}
138+
fmt(&format_args!(
139+
r#"
140+
assert_eq!(
141+
{prefix}_to_slice(&{rust_return_value}),
142+
{prefix}_to_slice(&{c_return_value}),
143+
"{{id}}-({i_plus_one}/{n})"
144+
);
183145
"#,
184-
ty = self.rust_intrinsic_name_prefix(),
185-
bl = self.inner_size(),
186-
rust_return_value = get(n, i, "__rust_return_value"),
187-
c_return_value = get(n, i, "__c_return_value"),
188-
i_plus_one = i + 1, // so that the output is "1/2" and "2/2"
189-
))
190-
}
191-
}
146+
rust_return_value = get(n, i, "__rust_return_value"),
147+
c_return_value = get(n, i, "__c_return_value"),
148+
i_plus_one = i + 1, // so that the output is "1/2" and "2/2"
149+
))
192150
})
193151
.to_string()
194152
}

0 commit comments

Comments
 (0)