in intrinsic-test, format f16 like C
This commit is contained in:
parent
42e6ad3ee8
commit
4f35c02aa0
2 changed files with 102 additions and 1 deletions
|
|
@ -121,14 +121,25 @@ impl Intrinsic {
|
|||
constraints
|
||||
};
|
||||
|
||||
// the `intrinsic-test` crate compares the output of C and Rust intrinsics. Currently, It uses
|
||||
// a string representation of the output value to compare. In C, f16 values are currently printed
|
||||
// as hexadecimal integers. Since https://github.com/rust-lang/rust/pull/127013, rust does print
|
||||
// them as decimal floating point values. To keep the intrinsics tests working, for now, format
|
||||
// vectors containing f16 values like C prints them.
|
||||
let return_value = match self.results.kind() {
|
||||
TypeKind::Float if self.results.inner_size() == 16 => "debug_f16(__return_value)",
|
||||
_ => "format_args!(\"{__return_value:.150?}\")",
|
||||
};
|
||||
|
||||
let indentation2 = indentation.nested();
|
||||
let indentation3 = indentation2.nested();
|
||||
|
||||
format!(
|
||||
"{indentation}for i in 0..{passes} {{\n\
|
||||
{indentation2}unsafe {{\n\
|
||||
{loaded_args}\
|
||||
{indentation3}let __return_value = {intrinsic_call}{const}({args});\n\
|
||||
{indentation3}println!(\"Result {additional}-{{}}: {{:.150?}}\", i + 1, __return_value);\n\
|
||||
{indentation3}println!(\"Result {additional}-{{}}: {{:?}}\", i + 1, {return_value});\n\
|
||||
{indentation2}}}\n\
|
||||
{indentation}}}",
|
||||
loaded_args = self.arguments.load_values_rust(indentation3),
|
||||
|
|
|
|||
|
|
@ -190,11 +190,99 @@ fn generate_rust_program(notices: &str, intrinsic: &Intrinsic, target: &str) ->
|
|||
.filter(|i| i.has_constraint())
|
||||
.collect_vec();
|
||||
|
||||
// Format f16 values (and vectors containing them) in a way that is consistent with C.
|
||||
let f16_formatting = r#"
|
||||
/// Used to continue `Debug`ging SIMD types as `MySimd(1, 2, 3, 4)`, as they
|
||||
/// were before moving to array-based simd.
|
||||
#[inline]
|
||||
fn debug_simd_finish<T: core::fmt::Debug, const N: usize>(
|
||||
formatter: &mut core::fmt::Formatter<'_>,
|
||||
type_name: &str,
|
||||
array: &[T; N],
|
||||
) -> core::fmt::Result {
|
||||
core::fmt::Formatter::debug_tuple_fields_finish(
|
||||
formatter,
|
||||
type_name,
|
||||
&core::array::from_fn::<&dyn core::fmt::Debug, N, _>(|i| &array[i]),
|
||||
)
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct Hex<T>(T);
|
||||
|
||||
impl<T: DebugHexF16> core::fmt::Debug for Hex<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
<T as DebugHexF16>::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
fn debug_f16<T: DebugHexF16>(x: T) -> impl core::fmt::Debug {
|
||||
Hex(x)
|
||||
}
|
||||
|
||||
trait DebugHexF16 {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result;
|
||||
}
|
||||
|
||||
impl DebugHexF16 for f16 {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "{:#06x?}", self.to_bits())
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugHexF16 for float16x4_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let array = unsafe { core::mem::transmute::<_, [Hex<f16>; 4]>(*self) };
|
||||
debug_simd_finish(f, "float16x4_t", &array)
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugHexF16 for float16x8_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let array = unsafe { core::mem::transmute::<_, [Hex<f16>; 8]>(*self) };
|
||||
debug_simd_finish(f, "float16x8_t", &array)
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugHexF16 for float16x4x2_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
debug_simd_finish(f, "float16x4x2_t", &[Hex(self.0), Hex(self.1)])
|
||||
}
|
||||
}
|
||||
impl DebugHexF16 for float16x4x3_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
debug_simd_finish(f, "float16x4x3_t", &[Hex(self.0), Hex(self.1), Hex(self.2)])
|
||||
}
|
||||
}
|
||||
impl DebugHexF16 for float16x4x4_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
debug_simd_finish(f, "float16x4x4_t", &[Hex(self.0), Hex(self.1), Hex(self.2), Hex(self.3)])
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugHexF16 for float16x8x2_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
debug_simd_finish(f, "float16x8x2_t", &[Hex(self.0), Hex(self.1)])
|
||||
}
|
||||
}
|
||||
impl DebugHexF16 for float16x8x3_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
debug_simd_finish(f, "float16x8x3_t", &[Hex(self.0), Hex(self.1), Hex(self.2)])
|
||||
}
|
||||
}
|
||||
impl DebugHexF16 for float16x8x4_t {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
debug_simd_finish(f, "float16x8x4_t", &[Hex(self.0), Hex(self.1), Hex(self.2), Hex(self.3)])
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let indentation = Indentation::default();
|
||||
format!(
|
||||
r#"{notices}#![feature(simd_ffi)]
|
||||
#![feature(link_llvm_intrinsics)]
|
||||
#![feature(f16)]
|
||||
#![feature(fmt_helpers_for_derive)]
|
||||
#![cfg_attr(target_arch = "arm", feature(stdarch_arm_neon_intrinsics))]
|
||||
#![cfg_attr(target_arch = "arm", feature(stdarch_aarch32_crc32))]
|
||||
#![cfg_attr(any(target_arch = "aarch64", target_arch = "arm64ec"), feature(stdarch_neon_fcma))]
|
||||
|
|
@ -207,6 +295,8 @@ fn generate_rust_program(notices: &str, intrinsic: &Intrinsic, target: &str) ->
|
|||
#![allow(non_upper_case_globals)]
|
||||
use core_arch::arch::{target_arch}::*;
|
||||
|
||||
{f16_formatting}
|
||||
|
||||
fn main() {{
|
||||
{arglists}
|
||||
{passes}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue