Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions simd/src/arm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,12 +604,12 @@ impl I32x4 {

#[inline]
pub fn max(self, other: I32x4) -> I32x4 {
unsafe { I32x4(simd_cast(simd_maximum_number_nsz(self.to_f32x4().0, other.to_f32x4().0))) }
unsafe { I32x4(aarch64::vmaxq_s32(self.0, other.0)) }
}

#[inline]
pub fn min(self, other: I32x4) -> I32x4 {
unsafe { I32x4(simd_cast(simd_minimum_number_nsz(self.to_f32x4().0, other.to_f32x4().0))) }
unsafe { I32x4(aarch64::vminq_s32(self.0, other.0)) }
}

// Packed comparisons
Expand Down
23 changes: 23 additions & 0 deletions simd/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,29 @@
use crate::default::{F32x4, I32x4, U32x4};
use crate::scalar::F32x4 as F32x4S;

#[cfg(all(pf_rustc_nightly, target_arch = "aarch64"))]
mod test_arm_i32x4_min_max_precision {
use crate::arm::I32x4;

#[test]
fn min_max_preserve_values_above_f32_integer_precision() {
// The ARM I32x4::{min,max} implementations must compare integer lanes directly.
// Converting through f32 loses precision above 2^24, so values such as 16_777_217
// round to neighboring integers and can produce a numerically wrong vector.
let a = I32x4::new(16_777_217, -16_777_217, 16_777_219, -16_777_219);
let b = I32x4::new(0, 0, 16_777_218, -16_777_218);

assert_eq!(
a.max(b),
I32x4::new(16_777_217, 0, 16_777_219, -16_777_218)
);
assert_eq!(
a.min(b),
I32x4::new(0, -16_777_217, 16_777_218, -16_777_219)
);
}
}

// F32x4

#[test]
Expand Down
Loading