cranelift: Add fadd/fsub/fmul/fdiv to interpreter (#4446)

Fuzzgen found these as soon as I added float support
This commit is contained in:
Afonso Bordado
2022-07-14 22:53:03 +01:00
committed by GitHub
parent fc72b7ccd3
commit 80976b6fc7
6 changed files with 658 additions and 5 deletions

View File

@@ -18,6 +18,7 @@ pub trait Value: Clone + From<DataValue> {
fn into_int(self) -> ValueResult<i128>;
fn float(n: u64, ty: Type) -> ValueResult<Self>;
fn into_float(self) -> ValueResult<f64>;
fn is_float(&self) -> bool;
fn is_nan(&self) -> ValueResult<bool>;
fn bool(b: bool, ty: Type) -> ValueResult<Self>;
fn into_bool(self) -> ValueResult<bool>;
@@ -250,6 +251,13 @@ impl Value for DataValue {
unimplemented!()
}
fn is_float(&self) -> bool {
match self {
DataValue::F32(_) | DataValue::F64(_) => true,
_ => false,
}
}
fn is_nan(&self) -> ValueResult<bool> {
match self {
DataValue::F32(f) => Ok(f.is_nan()),
@@ -457,19 +465,34 @@ impl Value for DataValue {
}
fn add(self, other: Self) -> ValueResult<Self> {
// TODO: floats must handle NaNs, +/-0
binary_match!(wrapping_add(&self, &other); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
if self.is_float() {
binary_match!(+(self, other); [F32, F64])
} else {
binary_match!(wrapping_add(&self, &other); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
}
}
fn sub(self, other: Self) -> ValueResult<Self> {
binary_match!(wrapping_sub(&self, &other); [I8, I16, I32, I64, I128]) // TODO: floats must handle NaNs, +/-0
if self.is_float() {
binary_match!(-(self, other); [F32, F64])
} else {
binary_match!(wrapping_sub(&self, &other); [I8, I16, I32, I64, I128])
}
}
fn mul(self, other: Self) -> ValueResult<Self> {
binary_match!(wrapping_mul(&self, &other); [I8, I16, I32, I64, I128])
if self.is_float() {
binary_match!(*(self, other); [F32, F64])
} else {
binary_match!(wrapping_mul(&self, &other); [I8, I16, I32, I64, I128])
}
}
fn div(self, other: Self) -> ValueResult<Self> {
if self.is_float() {
return binary_match!(/(self, other); [F32, F64]);
}
let denominator = other.clone().into_int()?;
// Check if we are dividing INT_MIN / -1. This causes an integer overflow trap.