From 6a20ca5512f8055845aca9f0fcb30504a151560a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 11 Jan 2023 16:24:39 -0800 Subject: [PATCH] Treat `wasmtime::component::Val::Float{32,64}` zero and negative zero as inequal (#5562) Following up on #5535, treat positive and negative zero as inequal in wasmtime::component::Val::Float{32,64}'s `PartialEq` logic. IEEE 754 equality considers these values equal, but they are semantically distinct values, and testing and fuzzing should be aware of the difference. --- crates/wasmtime/src/component/values.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/crates/wasmtime/src/component/values.rs b/crates/wasmtime/src/component/values.rs index 4816ac956601..81f0b70e16f3 100644 --- a/crates/wasmtime/src/component/values.rs +++ b/crates/wasmtime/src/component/values.rs @@ -1007,10 +1007,22 @@ impl Val { impl PartialEq for Val { fn eq(&self, other: &Self) -> bool { match (self, other) { - // This breaks conformance with IEEE-754 equality to simplify testing logic. - (Self::Float32(l), Self::Float32(r)) => l == r || (l.is_nan() && r.is_nan()), + // IEEE 754 equality considers NaN inequal to NaN and negative zero + // equal to positive zero, however we do the opposite here, because + // this logic is used by testing and fuzzing, which want to know + // whether two values are semantically the same, rather than + // numerically equal. + (Self::Float32(l), Self::Float32(r)) => { + (*l != 0.0 && l == r) + || (*l == 0.0 && l.to_bits() == r.to_bits()) + || (l.is_nan() && r.is_nan()) + } (Self::Float32(_), _) => false, - (Self::Float64(l), Self::Float64(r)) => l == r || (l.is_nan() && r.is_nan()), + (Self::Float64(l), Self::Float64(r)) => { + (*l != 0.0 && l == r) + || (*l == 0.0 && l.to_bits() == r.to_bits()) + || (l.is_nan() && r.is_nan()) + } (Self::Float64(_), _) => false, (Self::Bool(l), Self::Bool(r)) => l == r,