Skip to content

Commit f1b3623

Browse files
authored
Merge pull request RustPython#5086 from MannarAmuthan/float-int-ops
[JIT] Binary operations for integers and floating-point numbers allowing mixed type calculations
2 parents 91c0c8b + c2f159b commit f1b3623

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

jit/src/instructions.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
381381
// the rhs is popped off first
382382
let b = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
383383
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
384+
385+
let a_type = a.to_jit_type();
386+
let b_type = b.to_jit_type();
387+
384388
let val = match (op, a, b) {
385389
(BinaryOperator::Add, JitValue::Int(a), JitValue::Int(b)) => {
386390
let (out, carry) = self.builder.ins().iadd_ifcout(a, b);
@@ -443,6 +447,36 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
443447
(BinaryOperator::Divide, JitValue::Float(a), JitValue::Float(b)) => {
444448
JitValue::Float(self.builder.ins().fdiv(a, b))
445449
}
450+
451+
// Floats and Integers
452+
(_, JitValue::Int(a), JitValue::Float(b))
453+
| (_, JitValue::Float(a), JitValue::Int(b)) => {
454+
let operand_one = match a_type.unwrap() {
455+
JitType::Int => self.builder.ins().fcvt_from_sint(types::F64, a),
456+
_ => a,
457+
};
458+
459+
let operand_two = match b_type.unwrap() {
460+
JitType::Int => self.builder.ins().fcvt_from_sint(types::F64, b),
461+
_ => b,
462+
};
463+
464+
match op {
465+
BinaryOperator::Add => {
466+
JitValue::Float(self.builder.ins().fadd(operand_one, operand_two))
467+
}
468+
BinaryOperator::Subtract => {
469+
JitValue::Float(self.builder.ins().fsub(operand_one, operand_two))
470+
}
471+
BinaryOperator::Multiply => {
472+
JitValue::Float(self.builder.ins().fmul(operand_one, operand_two))
473+
}
474+
BinaryOperator::Divide => {
475+
JitValue::Float(self.builder.ins().fdiv(operand_one, operand_two))
476+
}
477+
_ => return Err(JitCompileError::NotSupported),
478+
}
479+
}
446480
_ => return Err(JitCompileError::NotSupported),
447481
};
448482
self.stack.push(val);

jit/tests/float_tests.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ fn test_add() {
3232
assert_eq!(add(1.0, f64::NEG_INFINITY), Ok(f64::NEG_INFINITY));
3333
}
3434

35+
#[test]
36+
fn test_add_with_integer() {
37+
let add = jit_function! { add(a:f64, b:i64) -> f64 => r##"
38+
def add(a: float, b: int):
39+
return a + b
40+
"## };
41+
42+
assert_approx_eq!(add(5.5, 10), Ok(15.5));
43+
assert_approx_eq!(add(-4.6, 7), Ok(2.4));
44+
assert_approx_eq!(add(-5.2, -3), Ok(-8.2));
45+
}
46+
3547
#[test]
3648
fn test_sub() {
3749
let sub = jit_function! { sub(a:f64, b:f64) -> f64 => r##"
@@ -49,6 +61,19 @@ fn test_sub() {
4961
assert_eq!(sub(1.0, f64::INFINITY), Ok(f64::NEG_INFINITY));
5062
}
5163

64+
#[test]
65+
fn test_sub_with_integer() {
66+
let sub = jit_function! { sub(a:i64, b:f64) -> f64 => r##"
67+
def sub(a: int, b: float):
68+
return a - b
69+
"## };
70+
71+
assert_approx_eq!(sub(5, 3.6), Ok(1.4));
72+
assert_approx_eq!(sub(3, -4.2), Ok(7.2));
73+
assert_approx_eq!(sub(-2, 1.3), Ok(-3.3));
74+
assert_approx_eq!(sub(-3, -1.3), Ok(-1.7));
75+
}
76+
5277
#[test]
5378
fn test_mul() {
5479
let mul = jit_function! { mul(a:f64, b:f64) -> f64 => r##"
@@ -70,6 +95,21 @@ fn test_mul() {
7095
assert_eq!(mul(f64::NEG_INFINITY, f64::INFINITY), Ok(f64::NEG_INFINITY));
7196
}
7297

98+
#[test]
99+
fn test_mul_with_integer() {
100+
let mul = jit_function! { mul(a:f64, b:i64) -> f64 => r##"
101+
def mul(a: float, b: int):
102+
return a * b
103+
"## };
104+
105+
assert_approx_eq!(mul(5.2, 2), Ok(10.4));
106+
assert_approx_eq!(mul(3.4, -1), Ok(-3.4));
107+
assert_bits_eq!(mul(1.0, 0), Ok(0.0f64));
108+
assert_bits_eq!(mul(-0.0, 1), Ok(-0.0f64));
109+
assert_bits_eq!(mul(0.0, -1), Ok(-0.0f64));
110+
assert_bits_eq!(mul(-0.0, -1), Ok(0.0f64));
111+
}
112+
73113
#[test]
74114
fn test_div() {
75115
let div = jit_function! { div(a:f64, b:f64) -> f64 => r##"
@@ -91,6 +131,23 @@ fn test_div() {
91131
assert_bits_eq!(div(-1.0, f64::INFINITY), Ok(-0.0f64));
92132
}
93133

134+
#[test]
135+
fn test_div_with_integer() {
136+
let div = jit_function! { div(a:f64, b:i64) -> f64 => r##"
137+
def div(a: float, b: int):
138+
return a / b
139+
"## };
140+
141+
assert_approx_eq!(div(5.2, 2), Ok(2.6));
142+
assert_approx_eq!(div(3.4, -1), Ok(-3.4));
143+
assert_eq!(div(1.0, 0), Ok(f64::INFINITY));
144+
assert_eq!(div(1.0, -0), Ok(f64::INFINITY));
145+
assert_eq!(div(-1.0, 0), Ok(f64::NEG_INFINITY));
146+
assert_eq!(div(-1.0, -0), Ok(f64::NEG_INFINITY));
147+
assert_eq!(div(f64::INFINITY, 2), Ok(f64::INFINITY));
148+
assert_eq!(div(f64::NEG_INFINITY, 3), Ok(f64::NEG_INFINITY));
149+
}
150+
94151
#[test]
95152
fn test_if_bool() {
96153
let if_bool = jit_function! { if_bool(a:f64) -> i64 => r##"

0 commit comments

Comments
 (0)