From fb90ac598144a469f0f19c45864b63ced86134bf Mon Sep 17 00:00:00 2001 From: "Kurt Heiritz (pseudo)" Date: Mon, 8 Dec 2025 18:44:49 +0800 Subject: [PATCH] Add support for f16 --- .../crates/core_simd/src/alias.rs | 10 ++++++++++ .../portable-simd/crates/core_simd/src/cast.rs | 5 +++++ .../portable-simd/crates/core_simd/src/iter.rs | 1 + .../portable-simd/crates/core_simd/src/lib.rs | 1 + .../portable-simd/crates/core_simd/src/ops.rs | 2 +- .../crates/core_simd/src/ops/unary.rs | 2 ++ .../crates/core_simd/src/simd/cmp/eq.rs | 2 +- .../crates/core_simd/src/simd/cmp/ord.rs | 2 +- .../crates/core_simd/src/simd/num/float.rs | 2 +- .../crates/core_simd/src/to_bytes.rs | 2 ++ .../crates/core_simd/src/vector.rs | 7 +++++++ .../portable-simd/crates/std_float/src/lib.rs | 18 ++++++++++++++++++ 12 files changed, 50 insertions(+), 4 deletions(-) diff --git a/library/portable-simd/crates/core_simd/src/alias.rs b/library/portable-simd/crates/core_simd/src/alias.rs index 23f121c46197c..6dcfcb660c26a 100644 --- a/library/portable-simd/crates/core_simd/src/alias.rs +++ b/library/portable-simd/crates/core_simd/src/alias.rs @@ -153,6 +153,16 @@ alias! { usizex64 64 } + f16 = { + f16x1 1 + f16x2 2 + f16x4 4 + f16x8 8 + f16x16 16 + f16x32 32 + f16x64 64 + } + f32 = { f32x1 1 f32x2 2 diff --git a/library/portable-simd/crates/core_simd/src/cast.rs b/library/portable-simd/crates/core_simd/src/cast.rs index 1c3592f807578..46792b2e76fc9 100644 --- a/library/portable-simd/crates/core_simd/src/cast.rs +++ b/library/portable-simd/crates/core_simd/src/cast.rs @@ -44,6 +44,11 @@ impl SimdCast for u64 {} unsafe impl Sealed for usize {} impl SimdCast for usize {} // Safety: primitive number types can be cast to other primitive number types + +unsafe impl Sealed for f16 {} + +impl SimdCast for f16 {} +// Safety: primitive number types can be cast to other primitive number types unsafe impl Sealed for f32 {} impl SimdCast for f32 {} // Safety: primitive number types can be cast to other primitive number types diff --git a/library/portable-simd/crates/core_simd/src/iter.rs b/library/portable-simd/crates/core_simd/src/iter.rs index b3732fd74d5f6..81724ce2da211 100644 --- a/library/portable-simd/crates/core_simd/src/iter.rs +++ b/library/portable-simd/crates/core_simd/src/iter.rs @@ -48,6 +48,7 @@ macro_rules! impl_traits { } } +impl_traits! { f16 } impl_traits! { f32 } impl_traits! { f64 } impl_traits! { u8 } diff --git a/library/portable-simd/crates/core_simd/src/lib.rs b/library/portable-simd/crates/core_simd/src/lib.rs index 717b882b64ba1..54ef790d32baa 100644 --- a/library/portable-simd/crates/core_simd/src/lib.rs +++ b/library/portable-simd/crates/core_simd/src/lib.rs @@ -4,6 +4,7 @@ convert_float_to_int, core_intrinsics, decl_macro, + f16_and_f128, intra_doc_pointers, repr_simd, simd_ffi, diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs index f36e8d01a73bb..f645c57b69b2e 100644 --- a/library/portable-simd/crates/core_simd/src/ops.rs +++ b/library/portable-simd/crates/core_simd/src/ops.rs @@ -248,7 +248,7 @@ for_base_ops! { // We don't need any special precautions here: // Floats always accept arithmetic ops, but may become NaN. for_base_ops! { - T = (f32, f64); + T = (f16, f32, f64); type Lhs = Simd; type Rhs = Simd; type Output = Self; diff --git a/library/portable-simd/crates/core_simd/src/ops/unary.rs b/library/portable-simd/crates/core_simd/src/ops/unary.rs index 412a5b801171b..82ed9c9160bdb 100644 --- a/library/portable-simd/crates/core_simd/src/ops/unary.rs +++ b/library/portable-simd/crates/core_simd/src/ops/unary.rs @@ -20,6 +20,8 @@ macro_rules! neg { } neg! { + impl Neg for Simd + impl Neg for Simd impl Neg for Simd diff --git a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs index 2312ba401fa78..2d69d57241edc 100644 --- a/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs +++ b/library/portable-simd/crates/core_simd/src/simd/cmp/eq.rs @@ -44,7 +44,7 @@ macro_rules! impl_number { } } -impl_number! { f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize } +impl_number! { f16, f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize } macro_rules! impl_mask { { $($integer:ty),* } => { diff --git a/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs b/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs index e813e7613032c..115e01b650251 100644 --- a/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs +++ b/library/portable-simd/crates/core_simd/src/simd/cmp/ord.rs @@ -150,7 +150,7 @@ macro_rules! impl_float { } } -impl_float! { f32, f64 } +impl_float! { f16, f32, f64 } macro_rules! impl_mask { { $($integer:ty),* } => { diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs index b5972c47373bb..2c91bd49e4f0e 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs @@ -450,4 +450,4 @@ macro_rules! impl_trait { } } -impl_trait! { f32 { bits: u32, mask: i32 }, f64 { bits: u64, mask: i64 } } +impl_trait! { f16 { bits: u16, mask: i16 }, f32 { bits: u32, mask: i32 }, f64 { bits: u64, mask: i64 } } diff --git a/library/portable-simd/crates/core_simd/src/to_bytes.rs b/library/portable-simd/crates/core_simd/src/to_bytes.rs index fee2cc06c5b09..51cc968bf9a2a 100644 --- a/library/portable-simd/crates/core_simd/src/to_bytes.rs +++ b/library/portable-simd/crates/core_simd/src/to_bytes.rs @@ -46,6 +46,7 @@ pub trait ToBytes: Sealed { } macro_rules! swap_bytes { + { f16, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) }; { f32, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) }; { f64, $x:expr } => { Simd::from_bits($x.to_bits().swap_bytes()) }; { $ty:ty, $x:expr } => { $x.swap_bytes() } @@ -141,5 +142,6 @@ impl_to_bytes! { isize, 4 } #[cfg(target_pointer_width = "64")] impl_to_bytes! { isize, 8 } +impl_to_bytes! { f16, 2 } impl_to_bytes! { f32, 4 } impl_to_bytes! { f64, 8 } diff --git a/library/portable-simd/crates/core_simd/src/vector.rs b/library/portable-simd/crates/core_simd/src/vector.rs index f40031f8c4da7..0b7d961f7de5f 100644 --- a/library/portable-simd/crates/core_simd/src/vector.rs +++ b/library/portable-simd/crates/core_simd/src/vector.rs @@ -1192,6 +1192,13 @@ unsafe impl SimdElement for isize { type Mask = isize; } +impl Sealed for f16 {} + +// Safety: f16 is a valid SIMD element type, and is supported by this API +unsafe impl SimdElement for f16 { + type Mask = i16; +} + impl Sealed for f32 {} // Safety: f32 is a valid SIMD element type, and is supported by this API diff --git a/library/portable-simd/crates/std_float/src/lib.rs b/library/portable-simd/crates/std_float/src/lib.rs index 148aa5f9f1771..8af7dd98f5ad7 100644 --- a/library/portable-simd/crates/std_float/src/lib.rs +++ b/library/portable-simd/crates/std_float/src/lib.rs @@ -140,6 +140,7 @@ pub trait StdFloat: Sealed + Sized { fn fract(self) -> Self; } +impl Sealed for Simd where LaneCount: SupportedLaneCount {} impl Sealed for Simd where LaneCount: SupportedLaneCount {} impl Sealed for Simd where LaneCount: SupportedLaneCount {} @@ -147,6 +148,23 @@ macro_rules! impl_float { { $($fn:ident: $intrinsic:ident,)* } => { + impl StdFloat for Simd + where + LaneCount: SupportedLaneCount, + { + #[inline] + fn fract(self) -> Self { + self - self.trunc() + } + + $( + #[inline] + fn $fn(self) -> Self { + unsafe { intrinsics::$intrinsic(self) } + } + )* + } + impl StdFloat for Simd where LaneCount: SupportedLaneCount,