Fix evaluating negative for floating point types

This commit is contained in:
hkalbasi 2023-05-17 01:27:45 +03:30
parent cbd14e9840
commit fd034bea1a
2 changed files with 30 additions and 13 deletions

View File

@ -113,6 +113,10 @@ fn floating_point() {
r#"const GOAL: f32 = 2.0 + 3.0 * 5.5 - 8.;"#,
i128::from_le_bytes(pad16(&f32::to_le_bytes(10.5), true)),
);
check_number(
r#"const GOAL: f32 = -90.0 + 36.0;"#,
i128::from_le_bytes(pad16(&f32::to_le_bytes(-54.0), true)),
);
}
#[test]

View File

@ -759,25 +759,38 @@ impl Evaluator<'_> {
let size = self.size_of_sized(&ty, locals, "operand of unary op")?;
c = self.read_memory(Address::from_bytes(c)?, size)?;
}
let mut c = c.to_vec();
if ty.as_builtin() == Some(BuiltinType::Bool) {
c[0] = 1 - c[0];
if let TyKind::Scalar(chalk_ir::Scalar::Float(f)) = ty.kind(Interner) {
match f {
chalk_ir::FloatTy::F32 => {
let c = -from_bytes!(f32, c);
Owned(c.to_le_bytes().into())
}
chalk_ir::FloatTy::F64 => {
let c = -from_bytes!(f32, c);
Owned(c.to_le_bytes().into())
}
}
} else {
match op {
UnOp::Not => c.iter_mut().for_each(|x| *x = !*x),
UnOp::Neg => {
c.iter_mut().for_each(|x| *x = !*x);
for k in c.iter_mut() {
let o;
(*k, o) = k.overflowing_add(1);
if !o {
break;
let mut c = c.to_vec();
if ty.as_builtin() == Some(BuiltinType::Bool) {
c[0] = 1 - c[0];
} else {
match op {
UnOp::Not => c.iter_mut().for_each(|x| *x = !*x),
UnOp::Neg => {
c.iter_mut().for_each(|x| *x = !*x);
for k in c.iter_mut() {
let o;
(*k, o) = k.overflowing_add(1);
if !o {
break;
}
}
}
}
}
Owned(c)
}
Owned(c)
}
Rvalue::CheckedBinaryOp(op, lhs, rhs) => {
let lc = self.eval_operand(lhs, locals)?;