fixing a bug with floationg point comparison

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-11-30 12:40:39 +01:00
parent a3355a59c0
commit a2ca8d98df
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
4 changed files with 87 additions and 10 deletions

View file

@ -705,6 +705,20 @@ main := fn(): uint {
### Purely Testing Examples
#### comparing_floating_points
```hb
main := fn(): uint {
if box(1) < box(0) return 1
if box(1) <= box(0) return 2
if box(0) > box(1) return 3
if box(0) >= box(1) return 4
return 0
}
box := fn(v: f32): f32 return v
box2 := fn(v: f64): f64 return v
```
#### pointer_comparison
```hb
main := fn(): int {

View file

@ -5771,6 +5771,7 @@ mod tests {
fb_driver;
// Purely Testing Examples;
comparing_floating_points;
pointer_comparison;
different_function_destinations;
triggering_store_in_divergent_branch;

View file

@ -0,0 +1,65 @@
box:
CP r13, r2
CP r1, r13
JALA r0, r31, 0a
main:
ADDI64 r254, r254, -32d
ST r31, r254, 0a, 32h
LI32 r32, 1065353216w
CP r2, r32
JAL r31, r0, :box
CP r33, r1
CP r2, r0
JAL r31, r0, :box
CP r34, r1
FCMPLT32 r33, r33, r34
ANDI r33, r33, 255d
JNE r33, r0, :0
CP r2, r32
JAL r31, r0, :box
CP r33, r1
CP r2, r0
JAL r31, r0, :box
CP r34, r1
FCMPGT32 r33, r33, r34
NOT r33, r33
ANDI r33, r33, 255d
JNE r33, r0, :1
CP r2, r0
JAL r31, r0, :box
CP r33, r1
CP r2, r32
JAL r31, r0, :box
CP r34, r1
FCMPGT32 r33, r33, r34
ANDI r33, r33, 255d
JNE r33, r0, :2
CP r2, r0
JAL r31, r0, :box
CP r33, r1
CP r2, r32
JAL r31, r0, :box
CP r32, r1
FCMPLT32 r32, r33, r32
NOT r32, r32
ANDI r32, r32, 255d
JNE r32, r0, :3
CP r1, r0
JMP :4
3: LI64 r32, 4d
CP r1, r32
JMP :4
2: LI64 r32, 3d
CP r1, r32
JMP :4
1: LI64 r32, 2d
CP r1, r32
JMP :4
0: LI64 r32, 1d
CP r1, r32
4: LD r31, r254, 0a, 32h
ADDI64 r254, r254, 32d
JALA r0, r31, 0a
code size: 355
ret: 0
status: Ok(())

View file

@ -307,10 +307,10 @@ where
.write_reg(tg, 1. / self.read_reg(reg).cast::<f32>())),
I::FINV64 => handler!(self, |OpsRR(tg, reg)| self
.write_reg(tg, 1. / self.read_reg(reg).cast::<f64>())),
I::FCMPLT32 => self.fcmp::<f32>(false, Ordering::Less),
I::FCMPLT64 => self.fcmp::<f64>(false, Ordering::Less),
I::FCMPGT32 => self.fcmp::<f32>(true, Ordering::Greater),
I::FCMPGT64 => self.fcmp::<f64>(true, Ordering::Greater),
I::FCMPLT32 => self.fcmp::<f32>(Ordering::Less),
I::FCMPLT64 => self.fcmp::<f64>(Ordering::Less),
I::FCMPGT32 => self.fcmp::<f32>(Ordering::Greater),
I::FCMPGT64 => self.fcmp::<f64>(Ordering::Greater),
I::ITF32 => handler!(self, |OpsRR(tg, reg)| self
.write_reg(tg, self.read_reg(reg).cast::<i64>() as f32)),
I::ITF64 => handler!(self, |OpsRR(tg, reg)| self
@ -512,14 +512,11 @@ where
/// Float comparsion
#[inline(always)]
unsafe fn fcmp<T: PartialOrd + ValueVariant>(&mut self, swapped: bool, expected: Ordering) {
unsafe fn fcmp<T: PartialOrd + ValueVariant>(&mut self, expected: Ordering) {
unsafe {
handler!(self, |OpsRRR(tg, a0, a1)| {
let mut a0 = self.read_reg(a0).cast::<T>();
let mut a1 = self.read_reg(a1).cast::<T>();
if swapped {
core::mem::swap(&mut a0, &mut a1);
}
let a0 = self.read_reg(a0).cast::<T>();
let a1 = self.read_reg(a1).cast::<T>();
self.write_reg(tg, (a0.partial_cmp(&a1) == Some(expected)) as u8)
});
}