diff --git a/src/shims/intrinsics/mod.rs b/src/shims/intrinsics/mod.rs index d54145dbdc..a9cf4bb0e2 100644 --- a/src/shims/intrinsics/mod.rs +++ b/src/shims/intrinsics/mod.rs @@ -324,7 +324,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "fmaf32" => { let [a, b, c] = check_arg_count(args)?; - // FIXME: Using host floats, to work around https://github.com/rust-lang/miri/issues/2468. + // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11 let a = f32::from_bits(this.read_scalar(a)?.to_u32()?); let b = f32::from_bits(this.read_scalar(b)?.to_u32()?); let c = f32::from_bits(this.read_scalar(c)?.to_u32()?); @@ -334,7 +334,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { "fmaf64" => { let [a, b, c] = check_arg_count(args)?; - // FIXME: Using host floats, to work around https://github.com/rust-lang/miri/issues/2468. + // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11 let a = f64::from_bits(this.read_scalar(a)?.to_u64()?); let b = f64::from_bits(this.read_scalar(b)?.to_u64()?); let c = f64::from_bits(this.read_scalar(c)?.to_u64()?); diff --git a/tests/pass/float.rs b/tests/pass/float.rs index fee5ca44ff..70c64485fe 100644 --- a/tests/pass/float.rs +++ b/tests/pass/float.rs @@ -168,6 +168,16 @@ fn basic() { let x: u32 = unsafe { std::mem::transmute(42.0_f32) }; let y: f32 = unsafe { std::mem::transmute(x) }; assert_eq(y, 42.0_f32); + + // `%` sign behavior, some of this used to be buggy + assert!((black_box(1.0f32) % 1.0).is_sign_positive()); + assert!((black_box(1.0f32) % -1.0).is_sign_positive()); + assert!((black_box(-1.0f32) % 1.0).is_sign_negative()); + assert!((black_box(-1.0f32) % -1.0).is_sign_negative()); + assert!((black_box(1.0f64) % 1.0).is_sign_positive()); + assert!((black_box(1.0f64) % -1.0).is_sign_positive()); + assert!((black_box(-1.0f64) % 1.0).is_sign_negative()); + assert!((black_box(-1.0f64) % -1.0).is_sign_negative()); } /// Many of these test values are taken from diff --git a/tests/pass/intrinsics-math.rs b/tests/pass/intrinsics-math.rs index e0e4f5654d..5f7730a3e8 100644 --- a/tests/pass/intrinsics-math.rs +++ b/tests/pass/intrinsics-math.rs @@ -1,4 +1,5 @@ #![feature(float_gamma)] +use std::{f32, f64}; macro_rules! assert_approx_eq { ($a:expr, $b:expr) => {{ @@ -15,8 +16,7 @@ fn ldexp(a: f64, b: i32) -> f64 { } pub fn main() { - use std::f32; - use std::f64; + mul_add(); assert_approx_eq!(64f32.sqrt(), 8f32); assert_approx_eq!(64f64.sqrt(), 8f64); @@ -48,13 +48,6 @@ pub fn main() { assert_approx_eq!(8f32.log2(), 3f32); assert_approx_eq!(f64::consts::E.log2(), f64::consts::LOG2_E); - assert_approx_eq!(3.0f32.mul_add(2.0f32, 5.0f32), 11.0); - assert_eq!(0.0f32.mul_add(-2.0, f32::consts::E), f32::consts::E); - assert_approx_eq!(3.0f64.mul_add(2.0, 5.0), 11.0); - assert_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E); - assert_eq!((-3.2f32).mul_add(2.4, f32::NEG_INFINITY), f32::NEG_INFINITY); - assert_eq!((-3.2f64).mul_add(2.4, f64::NEG_INFINITY), f64::NEG_INFINITY); - assert_approx_eq!((-1.0f32).abs(), 1.0f32); assert_approx_eq!(34.2f64.abs(), 34.2f64); @@ -146,3 +139,19 @@ pub fn main() { assert_approx_eq!(val, (2.0 * f64::consts::PI.sqrt()).ln()); assert_eq!(sign, -1); } + +fn mul_add() { + assert_approx_eq!(3.0f32.mul_add(2.0f32, 5.0f32), 11.0); + assert_eq!(0.0f32.mul_add(-2.0, f32::consts::E), f32::consts::E); + assert_approx_eq!(3.0f64.mul_add(2.0, 5.0), 11.0); + assert_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E); + assert_eq!((-3.2f32).mul_add(2.4, f32::NEG_INFINITY), f32::NEG_INFINITY); + assert_eq!((-3.2f64).mul_add(2.4, f64::NEG_INFINITY), f64::NEG_INFINITY); + + let f = f32::mul_add( + -0.000000000000000000000000000000000000014728589, + 0.0000037105144, + 0.000000000000000000000000000000000000000000055, + ); + assert_eq!(f.to_bits(), f32::to_bits(-0.0)); +}