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.;"#, r#"const GOAL: f32 = 2.0 + 3.0 * 5.5 - 8.;"#,
i128::from_le_bytes(pad16(&f32::to_le_bytes(10.5), true)), 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] #[test]

View file

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