cranelift: Fix fmin/fmax when dealing with zeroes (#4373)

`fmin`/`fmax` are defined as returning -0.0 as smaller than 0.0.
This is not how the IEEE754 views these values and the interpreter was
returning the wrong value in these operations since it was just using the
standard IEEE754 comparisons.

This also tries to preserve NaN information by avoiding passing NaN's
through any operation that could canonicalize it.
This commit is contained in:
Afonso Bordado
2022-07-05 20:59:23 +01:00
committed by GitHub
parent 41ba851a95
commit 925891245d
5 changed files with 263 additions and 10 deletions

View File

@@ -790,6 +790,16 @@ impl Ieee32 {
pub fn copysign(self, sign: Self) -> Self {
Self::with_float(self.as_f32().copysign(sign.as_f32()))
}
/// Returns true if self has a negative sign, including -0.0, NaNs with negative sign bit and negative infinity.
pub fn is_negative(&self) -> bool {
self.as_f32().is_sign_negative()
}
/// Returns true if self is positive or negative zero
pub fn is_zero(&self) -> bool {
self.as_f32() == 0.0
}
}
impl PartialOrd for Ieee32 {
@@ -909,6 +919,16 @@ impl Ieee64 {
pub fn copysign(self, sign: Self) -> Self {
Self::with_float(self.as_f64().copysign(sign.as_f64()))
}
/// Returns true if self has a negative sign, including -0.0, NaNs with negative sign bit and negative infinity.
pub fn is_negative(&self) -> bool {
self.as_f64().is_sign_negative()
}
/// Returns true if self is positive or negative zero
pub fn is_zero(&self) -> bool {
self.as_f64() == 0.0
}
}
impl PartialOrd for Ieee64 {