diff --git a/jit/src/instructions.rs b/jit/src/instructions.rs index f193e164a..26435d42c 100644 --- a/jit/src/instructions.rs +++ b/jit/src/instructions.rs @@ -270,6 +270,26 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> { let val = self.builder.ins().icmp(cond, a.val, b.val); self.stack.push(JitValue { + // TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8 + val: self.builder.ins().bint(types::I8, val), + ty: JitType::Bool, + }); + + Ok(()) + } + (JitType::Float, JitType::Float) => { + let cond = match op { + ComparisonOperator::Equal => FloatCC::Equal, + ComparisonOperator::NotEqual => FloatCC::NotEqual, + ComparisonOperator::Less => FloatCC::LessThan, + ComparisonOperator::LessOrEqual => FloatCC::LessThanOrEqual, + ComparisonOperator::Greater => FloatCC::GreaterThan, + ComparisonOperator::GreaterOrEqual => FloatCC::GreaterThanOrEqual, + }; + + let val = self.builder.ins().fcmp(cond, a.val, b.val); + self.stack.push(JitValue { + // TODO: Remove this `bint` in cranelift 0.90 as fcmp now returns i8 val: self.builder.ins().bint(types::I8, val), ty: JitType::Bool, }); diff --git a/jit/tests/float_tests.rs b/jit/tests/float_tests.rs index aa119000e..ae3fcd2c2 100644 --- a/jit/tests/float_tests.rs +++ b/jit/tests/float_tests.rs @@ -107,3 +107,105 @@ fn test_if_bool() { assert_eq!(if_bool(0.0), Ok(0)); } + +#[test] +fn test_float_eq() { + let float_eq = jit_function! { float_eq(a: f64, b: f64) -> bool => r##" + def float_eq(a: float, b: float): + return a == b + "## }; + + assert_eq!(float_eq(2.0, 2.0), Ok(true)); + assert_eq!(float_eq(3.4, -1.7), Ok(false)); + assert_eq!(float_eq(0.0, 0.0), Ok(true)); + assert_eq!(float_eq(-0.0, -0.0), Ok(true)); + assert_eq!(float_eq(-0.0, 0.0), Ok(true)); + assert_eq!(float_eq(-5.2, f64::NAN), Ok(false)); + assert_eq!(float_eq(f64::NAN, f64::NAN), Ok(false)); + assert_eq!(float_eq(f64::INFINITY, f64::NEG_INFINITY), Ok(false)); +} + +#[test] +fn test_float_ne() { + let float_ne = jit_function! { float_ne(a: f64, b: f64) -> bool => r##" + def float_ne(a: float, b: float): + return a != b + "## }; + + assert_eq!(float_ne(2.0, 2.0), Ok(false)); + assert_eq!(float_ne(3.4, -1.7), Ok(true)); + assert_eq!(float_ne(0.0, 0.0), Ok(false)); + assert_eq!(float_ne(-0.0, -0.0), Ok(false)); + assert_eq!(float_ne(-0.0, 0.0), Ok(false)); + assert_eq!(float_ne(-5.2, f64::NAN), Ok(true)); + assert_eq!(float_ne(f64::NAN, f64::NAN), Ok(true)); + assert_eq!(float_ne(f64::INFINITY, f64::NEG_INFINITY), Ok(true)); +} + +#[test] +fn test_float_gt() { + let float_gt = jit_function! { float_gt(a: f64, b: f64) -> bool => r##" + def float_gt(a: float, b: float): + return a > b + "## }; + + assert_eq!(float_gt(2.0, 2.0), Ok(false)); + assert_eq!(float_gt(3.4, -1.7), Ok(true)); + assert_eq!(float_gt(0.0, 0.0), Ok(false)); + assert_eq!(float_gt(-0.0, -0.0), Ok(false)); + assert_eq!(float_gt(-0.0, 0.0), Ok(false)); + assert_eq!(float_gt(-5.2, f64::NAN), Ok(false)); + assert_eq!(float_gt(f64::NAN, f64::NAN), Ok(false)); + assert_eq!(float_gt(f64::INFINITY, f64::NEG_INFINITY), Ok(true)); +} + +#[test] +fn test_float_gte() { + let float_gte = jit_function! { float_gte(a: f64, b: f64) -> bool => r##" + def float_gte(a: float, b: float): + return a >= b + "## }; + + assert_eq!(float_gte(2.0, 2.0), Ok(true)); + assert_eq!(float_gte(3.4, -1.7), Ok(true)); + assert_eq!(float_gte(0.0, 0.0), Ok(true)); + assert_eq!(float_gte(-0.0, -0.0), Ok(true)); + assert_eq!(float_gte(-0.0, 0.0), Ok(true)); + assert_eq!(float_gte(-5.2, f64::NAN), Ok(false)); + assert_eq!(float_gte(f64::NAN, f64::NAN), Ok(false)); + assert_eq!(float_gte(f64::INFINITY, f64::NEG_INFINITY), Ok(true)); +} + +#[test] +fn test_float_lt() { + let float_lt = jit_function! { float_lt(a: f64, b: f64) -> bool => r##" + def float_lt(a: float, b: float): + return a < b + "## }; + + assert_eq!(float_lt(2.0, 2.0), Ok(false)); + assert_eq!(float_lt(3.4, -1.7), Ok(false)); + assert_eq!(float_lt(0.0, 0.0), Ok(false)); + assert_eq!(float_lt(-0.0, -0.0), Ok(false)); + assert_eq!(float_lt(-0.0, 0.0), Ok(false)); + assert_eq!(float_lt(-5.2, f64::NAN), Ok(false)); + assert_eq!(float_lt(f64::NAN, f64::NAN), Ok(false)); + assert_eq!(float_lt(f64::INFINITY, f64::NEG_INFINITY), Ok(false)); +} + +#[test] +fn test_float_lte() { + let float_lte = jit_function! { float_lte(a: f64, b: f64) -> bool => r##" + def float_lte(a: float, b: float): + return a <= b + "## }; + + assert_eq!(float_lte(2.0, 2.0), Ok(true)); + assert_eq!(float_lte(3.4, -1.7), Ok(false)); + assert_eq!(float_lte(0.0, 0.0), Ok(true)); + assert_eq!(float_lte(-0.0, -0.0), Ok(true)); + assert_eq!(float_lte(-0.0, 0.0), Ok(true)); + assert_eq!(float_lte(-5.2, f64::NAN), Ok(false)); + assert_eq!(float_lte(f64::NAN, f64::NAN), Ok(false)); + assert_eq!(float_lte(f64::INFINITY, f64::NEG_INFINITY), Ok(false)); +}