From 3fbe59f8503fb5eb151bc995ba2c1ebad80dcbb5 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 6 Feb 2025 00:02:00 +0000 Subject: [PATCH] Print the hex float format upon failure Now that we have a hex float formatter, make use of it for test output. This produces values that are easier to read than the bitwise hex representation. Example: thread 'mp_quickspace_fmaf128' panicked at crates/libm-test/tests/multiprecision.rs:17:48: called `Result::unwrap()` on an `Err` value: input: (0xe38d71c71c71c71c71c71c71c71c71c8, 0xe38d71c71c71c71c71c71c71c71c71c8, 0xffff0000000000000000000000000000) as hex: (-0x1.71c71c71c71c71c71c71c71c71c8p+9102, -0x1.71c71c71c71c71c71c71c71c71c8p+9102, -inf) as bits: (0xe38d71c71c71c71c71c71c71c71c71c8, 0xe38d71c71c71c71c71c71c71c71c71c8, 0xffff0000000000000000000000000000) expected: 0xffff0000000000000000000000000000 -inf 0xffff0000000000000000000000000000 actual: 0x7fff8000000000000000000000000000 NaN 0x7fff8000000000000000000000000000 Caused by: real value != NaN --- .../libm/crates/libm-test/src/test_traits.rs | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/library/compiler-builtins/libm/crates/libm-test/src/test_traits.rs b/library/compiler-builtins/libm/crates/libm-test/src/test_traits.rs index a5806943e112..1bd5bce162bd 100644 --- a/library/compiler-builtins/libm/crates/libm-test/src/test_traits.rs +++ b/library/compiler-builtins/libm/crates/libm-test/src/test_traits.rs @@ -9,6 +9,7 @@ use std::fmt; use anyhow::{Context, anyhow, bail, ensure}; +use libm::support::Hexf; use crate::precision::CheckAction; use crate::{CheckCtx, Float, Int, MaybeOverride, SpecialCase, TestResult}; @@ -35,7 +36,10 @@ pub trait CheckOutput: Sized { /// /// This is only used for printing errors so allocating is okay. pub trait Hex: Copy { + /// Hex integer syntax. fn hex(self) -> String; + /// Hex float syntax. + fn hexf(self) -> String; } /* implement `TupleCall` */ @@ -128,6 +132,10 @@ where fn hex(self) -> String { format!("({},)", self.0.hex()) } + + fn hexf(self) -> String { + format!("({},)", self.0.hexf()) + } } impl Hex for (T1, T2) @@ -138,6 +146,10 @@ where fn hex(self) -> String { format!("({}, {})", self.0.hex(), self.1.hex()) } + + fn hexf(self) -> String { + format!("({}, {})", self.0.hexf(), self.1.hexf()) + } } impl Hex for (T1, T2, T3) @@ -149,6 +161,10 @@ where fn hex(self) -> String { format!("({}, {}, {})", self.0.hex(), self.1.hex(), self.2.hex()) } + + fn hexf(self) -> String { + format!("({}, {}, {})", self.0.hexf(), self.1.hexf(), self.2.hexf()) + } } /* trait implementations for ints */ @@ -160,6 +176,10 @@ macro_rules! impl_int { fn hex(self) -> String { format!("{self:#0width$x}", width = ((Self::BITS / 4) + 2) as usize) } + + fn hexf(self) -> String { + String::new() + } } impl $crate::CheckOutput for $ty @@ -234,6 +254,10 @@ macro_rules! impl_float { width = ((Self::BITS / 4) + 2) as usize ) } + + fn hexf(self) -> String { + format!("{}", Hexf(self)) + } } impl $crate::CheckOutput for $ty @@ -324,13 +348,18 @@ where res.with_context(|| { format!( "\ - \n input: {input:?} {ibits}\ - \n expected: {expected:<22?} {expbits}\ - \n actual: {actual:<22?} {actbits}\ + \n input: {input:?}\ + \n as hex: {ihex}\ + \n as bits: {ibits}\ + \n expected: {expected:<22?} {exphex} {expbits}\ + \n actual: {actual:<22?} {acthex} {actbits}\ ", - actbits = actual.hex(), - expbits = expected.hex(), + ihex = input.hexf(), ibits = input.hex(), + exphex = expected.hexf(), + expbits = expected.hex(), + actbits = actual.hex(), + acthex = actual.hexf(), ) }) } @@ -365,12 +394,15 @@ macro_rules! impl_tuples { .with_context(|| format!( "full context:\ \n input: {input:?} {ibits}\ + \n as hex: {ihex}\ + \n as bits: {ibits}\ \n expected: {expected:?} {expbits}\ \n actual: {self:?} {actbits}\ ", - actbits = self.hex(), - expbits = expected.hex(), + ihex = input.hexf(), ibits = input.hex(), + expbits = expected.hex(), + actbits = self.hex(), )) } }