Skip to content

Commit d9f006e

Browse files
authored
Merge pull request #2188 from sayantn/intrinsic-test-refactors
Simplify scalable vector testing
2 parents 3e757bc + c608e78 commit d9f006e

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

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)