Skip to content

Commit ab8faf3

Browse files
committed
Implement float comparisions in JIT
1 parent abc623e commit ab8faf3

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

jit/src/instructions.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,26 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
270270

271271
let val = self.builder.ins().icmp(cond, a.val, b.val);
272272
self.stack.push(JitValue {
273+
// TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8
274+
val: self.builder.ins().bint(types::I8, val),
275+
ty: JitType::Bool,
276+
});
277+
278+
Ok(())
279+
}
280+
(JitType::Float, JitType::Float) => {
281+
let cond = match op {
282+
ComparisonOperator::Equal => FloatCC::Equal,
283+
ComparisonOperator::NotEqual => FloatCC::NotEqual,
284+
ComparisonOperator::Less => FloatCC::LessThan,
285+
ComparisonOperator::LessOrEqual => FloatCC::LessThanOrEqual,
286+
ComparisonOperator::Greater => FloatCC::GreaterThan,
287+
ComparisonOperator::GreaterOrEqual => FloatCC::GreaterThanOrEqual,
288+
};
289+
290+
let val = self.builder.ins().fcmp(cond, a.val, b.val);
291+
self.stack.push(JitValue {
292+
// TODO: Remove this `bint` in cranelift 0.90 as fcmp now returns i8
273293
val: self.builder.ins().bint(types::I8, val),
274294
ty: JitType::Bool,
275295
});

jit/tests/float_tests.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,105 @@ fn test_if_bool() {
107107

108108
assert_eq!(if_bool(0.0), Ok(0));
109109
}
110+
111+
#[test]
112+
fn test_float_eq() {
113+
let float_eq = jit_function! { float_eq(a: f64, b: f64) -> bool => r##"
114+
def float_eq(a: float, b: float):
115+
return a == b
116+
"## };
117+
118+
assert_eq!(float_eq(2.0, 2.0), Ok(true));
119+
assert_eq!(float_eq(3.4, -1.7), Ok(false));
120+
assert_eq!(float_eq(0.0, 0.0), Ok(true));
121+
assert_eq!(float_eq(-0.0, -0.0), Ok(true));
122+
assert_eq!(float_eq(-0.0, 0.0), Ok(true));
123+
assert_eq!(float_eq(-5.2, f64::NAN), Ok(false));
124+
assert_eq!(float_eq(f64::NAN, f64::NAN), Ok(false));
125+
assert_eq!(float_eq(f64::INFINITY, f64::NEG_INFINITY), Ok(false));
126+
}
127+
128+
#[test]
129+
fn test_float_ne() {
130+
let float_ne = jit_function! { float_ne(a: f64, b: f64) -> bool => r##"
131+
def float_ne(a: float, b: float):
132+
return a != b
133+
"## };
134+
135+
assert_eq!(float_ne(2.0, 2.0), Ok(false));
136+
assert_eq!(float_ne(3.4, -1.7), Ok(true));
137+
assert_eq!(float_ne(0.0, 0.0), Ok(false));
138+
assert_eq!(float_ne(-0.0, -0.0), Ok(false));
139+
assert_eq!(float_ne(-0.0, 0.0), Ok(false));
140+
assert_eq!(float_ne(-5.2, f64::NAN), Ok(true));
141+
assert_eq!(float_ne(f64::NAN, f64::NAN), Ok(true));
142+
assert_eq!(float_ne(f64::INFINITY, f64::NEG_INFINITY), Ok(true));
143+
}
144+
145+
#[test]
146+
fn test_float_gt() {
147+
let float_gt = jit_function! { float_gt(a: f64, b: f64) -> bool => r##"
148+
def float_gt(a: float, b: float):
149+
return a > b
150+
"## };
151+
152+
assert_eq!(float_gt(2.0, 2.0), Ok(false));
153+
assert_eq!(float_gt(3.4, -1.7), Ok(true));
154+
assert_eq!(float_gt(0.0, 0.0), Ok(false));
155+
assert_eq!(float_gt(-0.0, -0.0), Ok(false));
156+
assert_eq!(float_gt(-0.0, 0.0), Ok(false));
157+
assert_eq!(float_gt(-5.2, f64::NAN), Ok(false));
158+
assert_eq!(float_gt(f64::NAN, f64::NAN), Ok(false));
159+
assert_eq!(float_gt(f64::INFINITY, f64::NEG_INFINITY), Ok(true));
160+
}
161+
162+
#[test]
163+
fn test_float_gte() {
164+
let float_gte = jit_function! { float_gte(a: f64, b: f64) -> bool => r##"
165+
def float_gte(a: float, b: float):
166+
return a >= b
167+
"## };
168+
169+
assert_eq!(float_gte(2.0, 2.0), Ok(true));
170+
assert_eq!(float_gte(3.4, -1.7), Ok(true));
171+
assert_eq!(float_gte(0.0, 0.0), Ok(true));
172+
assert_eq!(float_gte(-0.0, -0.0), Ok(true));
173+
assert_eq!(float_gte(-0.0, 0.0), Ok(true));
174+
assert_eq!(float_gte(-5.2, f64::NAN), Ok(false));
175+
assert_eq!(float_gte(f64::NAN, f64::NAN), Ok(false));
176+
assert_eq!(float_gte(f64::INFINITY, f64::NEG_INFINITY), Ok(true));
177+
}
178+
179+
#[test]
180+
fn test_float_lt() {
181+
let float_lt = jit_function! { float_lt(a: f64, b: f64) -> bool => r##"
182+
def float_lt(a: float, b: float):
183+
return a < b
184+
"## };
185+
186+
assert_eq!(float_lt(2.0, 2.0), Ok(false));
187+
assert_eq!(float_lt(3.4, -1.7), Ok(false));
188+
assert_eq!(float_lt(0.0, 0.0), Ok(false));
189+
assert_eq!(float_lt(-0.0, -0.0), Ok(false));
190+
assert_eq!(float_lt(-0.0, 0.0), Ok(false));
191+
assert_eq!(float_lt(-5.2, f64::NAN), Ok(false));
192+
assert_eq!(float_lt(f64::NAN, f64::NAN), Ok(false));
193+
assert_eq!(float_lt(f64::INFINITY, f64::NEG_INFINITY), Ok(false));
194+
}
195+
196+
#[test]
197+
fn test_float_lte() {
198+
let float_lte = jit_function! { float_lte(a: f64, b: f64) -> bool => r##"
199+
def float_lte(a: float, b: float):
200+
return a <= b
201+
"## };
202+
203+
assert_eq!(float_lte(2.0, 2.0), Ok(true));
204+
assert_eq!(float_lte(3.4, -1.7), Ok(false));
205+
assert_eq!(float_lte(0.0, 0.0), Ok(true));
206+
assert_eq!(float_lte(-0.0, -0.0), Ok(true));
207+
assert_eq!(float_lte(-0.0, 0.0), Ok(true));
208+
assert_eq!(float_lte(-5.2, f64::NAN), Ok(false));
209+
assert_eq!(float_lte(f64::NAN, f64::NAN), Ok(false));
210+
assert_eq!(float_lte(f64::INFINITY, f64::NEG_INFINITY), Ok(false));
211+
}

0 commit comments

Comments
 (0)