Skip to content

Commit

Permalink
Macros are working for all f128 cases
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed May 10, 2024
1 parent ba6162c commit 0facad1
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 78 deletions.
55 changes: 11 additions & 44 deletions testcrate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,74 +267,41 @@ pub fn fuzz_float_2<F: Float, E: Fn(F, F)>(n: u32, f: E) {
/// Use the builtin operation if avialable, fallback to apfloat if not
#[macro_export]
macro_rules! apfloat_fallback {
// binary
(
$float_ty:ty,
$apfloat_ty:ident,
$x:expr,
$y:expr,
$op:expr,
$sys_available:meta
// $(, ret_float=false)?
$(, $($convert_args:tt)*)?
$sys_available:meta,
$op:expr $(=> $convert:ident)?,
$($arg:expr),+
$(,)?
) => {{
#[cfg($sys_available)]
let ret = {
type FloatTy = $float_ty;
$op($x, $y)
$op( $($arg),+ )
};

#[cfg(not($sys_available))]
let ret = {
use rustc_apfloat::Float;
type FloatTy = rustc_apfloat::ieee::$apfloat_ty;

let x_ap = FloatTy::from_bits($x.to_bits().into());
let y_ap = FloatTy::from_bits($y.to_bits().into());
let op_res = $op( $(FloatTy::from_bits($arg.to_bits().into())),+ );

apfloat_fallback!(@convert $float_ty, $op(x_ap, y_ap), $($($convert_args)*)?)
apfloat_fallback!(@convert $float_ty, op_res $(,$convert)?)
};

ret
}};

// unary
(
$float_ty:ty,
$apfloat_ty:ident,
$x:expr,
$op:expr,
$sys_available:meta
$(, $($convert_args:tt)*)?
$(,)?
) => {{
#[cfg($sys_available)]
let ret = {
type FloatTy = $float_ty;
$op($x)
};

#[cfg(not($sys_available))]
let ret = {
use rustc_apfloat::Float;
type FloatTy = rustc_apfloat::ieee::$apfloat_ty;

let x_ap = FloatTy::from_bits($x.to_bits().into());
apfloat_fallback!(@convert $float_ty, $op(x_ap), $($($convert_args)*)?)
};

ret
}};


// Other operations do not need unwrapping
(@convert $float_ty:ty, $val:expr, ret_float=false) => {
// Operations that do not need converting back to a float
(@convert $float_ty:ty, $val:expr, no_convert) => {
$val
};

// Some apfloat operations return a `StatusAnd` that we need to extract the value from
(@convert $float_ty:ty, $val:expr,) => {{
// Some apfloat operations return a `StatusAnd` that we need to extract the value from. This
// is the default.
(@convert $float_ty:ty, $val:expr) => {{
// ignore the status, just get the value
let unwrapped = $val.value;

Expand Down
4 changes: 2 additions & 2 deletions testcrate/tests/addsub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ macro_rules! float_sum {
($($f:ty, $fn_add:ident, $fn_sub:ident, $apfloat_ty:ident, $sys_available:meta);*;) => {
$(
fuzz_float_2(N, |x: $f, y: $f| {
let add0 = apfloat_fallback!($f, $apfloat_ty, x, y, Add::add, $sys_available);
let sub0 = apfloat_fallback!($f, $apfloat_ty, x, y, Sub::sub, $sys_available);
let add0 = apfloat_fallback!($f, $apfloat_ty, $sys_available, Add::add, x, y);
let sub0 = apfloat_fallback!($f, $apfloat_ty, $sys_available, Sub::sub, x, y);
let add1: $f = $fn_add(x, y);
let sub1: $f = $fn_sub(x, y);
if !Float::eq_repr(add0, add1) {
Expand Down
61 changes: 31 additions & 30 deletions testcrate/tests/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,40 @@ macro_rules! cmp {
$($unordered_val:expr, $fn:ident);*;
) => {
$(
let cmp0 = if apfloat_fallback!($f, $apfloat_ty, $x,
|x: FloatTy| x.is_nan(),
$sys_available, ret_float = false
) || apfloat_fallback!($f, $apfloat_ty, $y,
|y: FloatTy| y.is_nan(),
$sys_available, ret_float = false
println!("a");
let cmp0 = if apfloat_fallback!(
$f, $apfloat_ty, $sys_available,
|x: FloatTy| x.is_nan() => no_convert,
$x
) || apfloat_fallback!(
$f, $apfloat_ty, $sys_available,
|y: FloatTy| y.is_nan() => no_convert,
$y
)
{
$unordered_val
} else if apfloat_fallback!($f, $apfloat_ty, $x, $y,
|x, y| x < y,
$sys_available, ret_float = false
} else if apfloat_fallback!(
$f, $apfloat_ty, $sys_available,
|x, y| x < y => no_convert,
$x, $y
) {
-1
} else if apfloat_fallback!($f, $apfloat_ty, $x, $y,
|x, y| x == y,
$sys_available, ret_float = false
} else if apfloat_fallback!(
$f, $apfloat_ty, $sys_available,
|x, y| x == y => no_convert,
$x, $y
) {
0
} else {
1
};
println!("b");

let cmp1 = $fn($x, $y);
if cmp0 != cmp1 {
panic!(
"{}({:?}, {:?}): std: {:?}, builtins: {:?}",
stringify!($fn_builtins), $x, $y, cmp0, cmp1
stringify!($fn), $x, $y, cmp0, cmp1
);
}
)*
Expand Down Expand Up @@ -84,23 +90,18 @@ fn float_comparisons() {
};

fuzz_float_2(N, |x: f128, y: f128| {
// let x_isnan = apfloat_fallback!(
// f128,
// Quad,
// x,
// |x: FloatTy| x.is_nan(),
// not(feature = "no-sys-f128"),
// ret_float = false
// );
// let y_isnan = apfloat_fallback!(
// f128,
// Quad,
// y,
// |y: FloatTy| y.is_nan(),
// not(feature = "no-sys-f128"),
// ret_float = false
// );
// assert_eq!(__unordtf2(x, y) != 0, x_isnan || y_isnan);
let x_is_nan = apfloat_fallback!(
f128, Quad, not(feature = "no-sys-f128"),
|x: FloatTy| x.is_nan() => no_convert,
x
);
let y_is_nan = apfloat_fallback!(
f128, Quad, not(feature = "no-sys-f128"),
|x: FloatTy| x.is_nan() => no_convert,
y
);

assert_eq!(__unordtf2(x, y) != 0, x_is_nan || y_is_nan);

cmp!(f128, x, y, Quad, not(feature = "no-sys-f128"),
1, __lttf2;
Expand Down
2 changes: 1 addition & 1 deletion testcrate/tests/div_rem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ macro_rules! float {
($($f:ty, $fn:ident, $apfloat_ty:ident, $sys_available:meta);*;) => {
$(
fuzz_float_2(N, |x: $f, y: $f| {
let quo0: $f = apfloat_fallback!($f, $apfloat_ty, x, y, Div::div, $sys_available);
let quo0: $f = apfloat_fallback!($f, $apfloat_ty, $sys_available, Div::div, x, y);
let quo1: $f = $fn(x, y);
#[cfg(not(target_arch = "arm"))]
if !Float::eq_repr(quo0, quo1) {
Expand Down
2 changes: 1 addition & 1 deletion testcrate/tests/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ macro_rules! float_mul {
($($f:ty, $fn:ident, $apfloat_ty:ident, $sys_available:meta);*;) => {
$(
fuzz_float_2(N, |x: $f, y: $f| {
let mul0 = apfloat_fallback!($f, $apfloat_ty, x, y, Mul::mul, $sys_available);
let mul0 = apfloat_fallback!($f, $apfloat_ty, $sys_available, Mul::mul, x, y);
let mul1: $f = $fn(x, y);
// multiplication of subnormals is not currently handled
if !(Float::is_subnormal(mul0) || Float::is_subnormal(mul1)) {
Expand Down

0 comments on commit 0facad1

Please sign in to comment.