From 42e0c8c0a1cabb24b48f56470aea1656a47f9cc7 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 10 Jul 2019 12:59:36 +0200 Subject: [PATCH 1/2] Add FMA tests that cause it to segfault --- .../compiler-builtins/libm/src/math/fma.rs | 19 +++++++++++++++++++ library/compiler-builtins/libm/tests/unit.rs | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 library/compiler-builtins/libm/tests/unit.rs diff --git a/library/compiler-builtins/libm/src/math/fma.rs b/library/compiler-builtins/libm/src/math/fma.rs index 07d90f8b727d..6d4471a9a04f 100644 --- a/library/compiler-builtins/libm/src/math/fma.rs +++ b/library/compiler-builtins/libm/src/math/fma.rs @@ -205,3 +205,22 @@ pub fn fma(x: f64, y: f64, z: f64) -> f64 { } scalbn(r, e) } + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn fma_segfault() { + // These two inputs cause fma to segfault on release due to overflow: + assert_eq!( + fma( + -0.0000000000000002220446049250313, + -0.0000000000000002220446049250313, + -0.0000000000000002220446049250313 + ), + -0.00000000000000022204460492503126, + ); + + assert_eq!(fma(-0.992, -0.992, -0.992), -0.00793599999988632,); + } +} diff --git a/library/compiler-builtins/libm/tests/unit.rs b/library/compiler-builtins/libm/tests/unit.rs new file mode 100644 index 000000000000..4e7002817a64 --- /dev/null +++ b/library/compiler-builtins/libm/tests/unit.rs @@ -0,0 +1,19 @@ +use libm::*; + +#[test] +fn fma_segfault() { + // These two inputs cause fma to segfault on release due to overflow: + assert_eq!( + fma( + -0.0000000000000002220446049250313, + -0.0000000000000002220446049250313, + -0.0000000000000002220446049250313 + ), + -0.00000000000000022204460492503126, + ); + + assert_eq!( + fma(-0.992, -0.992, -0.992), + -0.00793599999988632, + ); +} From c2b0bbb814544d8c8ccc662b6294948629f0ceb6 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Wed, 10 Jul 2019 13:01:02 +0200 Subject: [PATCH 2/2] Fix overflow bug in fma --- .../compiler-builtins/libm/src/math/fma.rs | 4 ++-- library/compiler-builtins/libm/tests/unit.rs | 19 ------------------- 2 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 library/compiler-builtins/libm/tests/unit.rs diff --git a/library/compiler-builtins/libm/src/math/fma.rs b/library/compiler-builtins/libm/src/math/fma.rs index 6d4471a9a04f..99f77bc7967a 100644 --- a/library/compiler-builtins/libm/src/math/fma.rs +++ b/library/compiler-builtins/libm/src/math/fma.rs @@ -126,8 +126,8 @@ pub fn fma(x: f64, y: f64, z: f64) -> f64 { } else { /* r -= z */ let t = rlo; - rlo -= zlo; - rhi = rhi - zhi - (t < rlo) as u64; + rlo = rlo.wrapping_sub(zlo); + rhi = rhi.wrapping_sub(zhi.wrapping_sub((t < rlo) as u64)); if (rhi >> 63) != 0 { rlo = (-(rlo as i64)) as u64; rhi = (-(rhi as i64)) as u64 - (rlo != 0) as u64; diff --git a/library/compiler-builtins/libm/tests/unit.rs b/library/compiler-builtins/libm/tests/unit.rs deleted file mode 100644 index 4e7002817a64..000000000000 --- a/library/compiler-builtins/libm/tests/unit.rs +++ /dev/null @@ -1,19 +0,0 @@ -use libm::*; - -#[test] -fn fma_segfault() { - // These two inputs cause fma to segfault on release due to overflow: - assert_eq!( - fma( - -0.0000000000000002220446049250313, - -0.0000000000000002220446049250313, - -0.0000000000000002220446049250313 - ), - -0.00000000000000022204460492503126, - ); - - assert_eq!( - fma(-0.992, -0.992, -0.992), - -0.00793599999988632, - ); -}