diff --git a/patches/0001-portable-simd-Disable-f16-usage-in-portable-simd.patch b/patches/0001-portable-simd-Disable-f16-usage-in-portable-simd.patch deleted file mode 100644 index a2fcd97349..0000000000 --- a/patches/0001-portable-simd-Disable-f16-usage-in-portable-simd.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 2aa88b261ffb51d3f18a4b9d3b79232d7445e5f3 Mon Sep 17 00:00:00 2001 -From: bjorn3 <17426603+bjorn3@users.noreply.github.com> -Date: Thu, 16 Apr 2026 17:29:02 +0200 -Subject: [PATCH] Disable f16 usage in portable-simd - -It is currently broken on x86_64-pc-windows-gnu ---- - Cargo.toml | 8 ++------ - crates/core_simd/src/alias.rs | 10 ---------- - crates/core_simd/src/cast.rs | 3 --- - crates/core_simd/src/lib.rs | 1 - - 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/vector.rs | 7 ------- - crates/core_simd/tests/f16_ops.rs | 10 ---------- - crates/std_float/src/lib.rs | 9 --------- - crates/test_helpers/src/biteq.rs | 2 +- - crates/test_helpers/src/lib.rs | 2 -- - crates/test_helpers/src/subnormals.rs | 2 +- - 15 files changed, 8 insertions(+), 56 deletions(-) - delete mode 100644 crates/core_simd/tests/f16_ops.rs - -diff --git a/Cargo.toml b/Cargo.toml -index 883140b..45296b4 100644 ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -1,10 +1,6 @@ - [workspace] - resolver = "1" --members = [ -- "crates/core_simd", -- "crates/std_float", -- "crates/test_helpers", --] -+members = ["crates/core_simd", "crates/std_float", "crates/test_helpers"] - - [profile.test.package."*"] - opt-level = 2 -@@ -15,4 +11,4 @@ opt-level = 2 - [workspace.dependencies.proptest] - version = "1.11" - default-features = false --features = ["alloc", "f16"] -+features = ["alloc"] -diff --git a/crates/core_simd/src/alias.rs b/crates/core_simd/src/alias.rs -index 6dcfcb6..23f121c 100644 ---- a/crates/core_simd/src/alias.rs -+++ b/crates/core_simd/src/alias.rs -@@ -153,16 +153,6 @@ 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/crates/core_simd/src/cast.rs b/crates/core_simd/src/cast.rs -index 69dc7ba..1c3592f 100644 ---- a/crates/core_simd/src/cast.rs -+++ b/crates/core_simd/src/cast.rs -@@ -44,9 +44,6 @@ 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/crates/core_simd/src/lib.rs b/crates/core_simd/src/lib.rs -index 413a886..115be44 100644 ---- a/crates/core_simd/src/lib.rs -+++ b/crates/core_simd/src/lib.rs -@@ -1,7 +1,6 @@ - #![no_std] - #![feature( - convert_float_to_int, -- f16, - core_intrinsics, - decl_macro, - repr_simd, -diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs -index c0a06ed..eb6601f 100644 ---- a/crates/core_simd/src/ops.rs -+++ b/crates/core_simd/src/ops.rs -@@ -245,7 +245,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 = (f16, f32, f64); -+ T = (f32, f64); - type Lhs = Simd; - type Rhs = Simd; - type Output = Self; -diff --git a/crates/core_simd/src/ops/unary.rs b/crates/core_simd/src/ops/unary.rs -index af7aa8a..e1c0616 100644 ---- a/crates/core_simd/src/ops/unary.rs -+++ b/crates/core_simd/src/ops/unary.rs -@@ -19,8 +19,6 @@ macro_rules! neg { - } - - neg! { -- impl Neg for Simd -- - impl Neg for Simd - - impl Neg for Simd -diff --git a/crates/core_simd/src/simd/cmp/eq.rs b/crates/core_simd/src/simd/cmp/eq.rs -index 7683640..d553d6c 100644 ---- a/crates/core_simd/src/simd/cmp/eq.rs -+++ b/crates/core_simd/src/simd/cmp/eq.rs -@@ -42,7 +42,7 @@ macro_rules! impl_number { - } - } - --impl_number! { f16, f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize } -+impl_number! { f32, f64, u8, u16, u32, u64, usize, i8, i16, i32, i64, isize } - - macro_rules! impl_mask { - { $($integer:ty),* } => { -diff --git a/crates/core_simd/src/simd/cmp/ord.rs b/crates/core_simd/src/simd/cmp/ord.rs -index 5a4e74c..5672fbb 100644 ---- a/crates/core_simd/src/simd/cmp/ord.rs -+++ b/crates/core_simd/src/simd/cmp/ord.rs -@@ -144,7 +144,7 @@ macro_rules! impl_float { - } - } - --impl_float! { f16, f32, f64 } -+impl_float! { f32, f64 } - - macro_rules! impl_mask { - { $($integer:ty),* } => { -diff --git a/crates/core_simd/src/simd/num/float.rs b/crates/core_simd/src/simd/num/float.rs -index 510f4c9..175cbce 100644 ---- a/crates/core_simd/src/simd/num/float.rs -+++ b/crates/core_simd/src/simd/num/float.rs -@@ -444,4 +444,4 @@ macro_rules! impl_trait { - } - } - --impl_trait! { f16 { bits: u16, mask: i16 }, f32 { bits: u32, mask: i32 }, f64 { bits: u64, mask: i64 } } -+impl_trait! { f32 { bits: u32, mask: i32 }, f64 { bits: u64, mask: i64 } } -diff --git a/crates/core_simd/src/simd/prelude.rs b/crates/core_simd/src/simd/prelude.rs -index 51b8def..6e93f16 100644 ---- a/crates/core_simd/src/simd/prelude.rs -+++ b/crates/core_simd/src/simd/prelude.rs -@@ -14,10 +14,6 @@ pub use super::{ - simd_swizzle, - }; - --#[rustfmt::skip] --#[doc(no_inline)] --pub use super::{f16x1, f16x2, f16x4, f16x8, f16x16, f16x32, f16x64}; -- - #[rustfmt::skip] - #[doc(no_inline)] - pub use super::{f32x1, f32x2, f32x4, f32x8, f32x16, f32x32, f32x64}; -diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs -index fbef69f..c8e0b8c 100644 ---- a/crates/core_simd/src/vector.rs -+++ b/crates/core_simd/src/vector.rs -@@ -1146,13 +1146,6 @@ 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/crates/core_simd/tests/f16_ops.rs b/crates/core_simd/tests/f16_ops.rs -deleted file mode 100644 -index f89bdf4..0000000 ---- a/crates/core_simd/tests/f16_ops.rs -+++ /dev/null -@@ -1,10 +0,0 @@ --#![feature(portable_simd)] --#![feature(f16)] -- --#[macro_use] --mod ops_macros; -- --// FIXME: some f16 operations cause rustc to hang on wasm simd --// https://github.com/llvm/llvm-project/issues/189251 --#[cfg(not(all(target_arch = "wasm32", target_feature = "simd128")))] --impl_float_tests! { f16, i16 } -diff --git a/crates/std_float/src/lib.rs b/crates/std_float/src/lib.rs -index ff35254..acc1bfc 100644 ---- a/crates/std_float/src/lib.rs -+++ b/crates/std_float/src/lib.rs -@@ -2,7 +2,6 @@ - feature = "as_crate", - feature(core_intrinsics), - feature(portable_simd), -- feature(f16), - allow(internal_features) - )] - #[cfg(not(feature = "as_crate"))] -@@ -170,17 +169,9 @@ pub trait StdFloat: Sealed + Sized { - fn fract(self) -> Self; - } - --impl Sealed for Simd {} - impl Sealed for Simd {} - impl Sealed for Simd {} - --impl StdFloat for Simd { -- #[inline] -- fn fract(self) -> Self { -- self - self.trunc() -- } --} -- - impl StdFloat for Simd { - #[inline] - fn fract(self) -> Self { -diff --git a/crates/test_helpers/src/biteq.rs b/crates/test_helpers/src/biteq.rs -index 36761e3..cbc20cd 100644 ---- a/crates/test_helpers/src/biteq.rs -+++ b/crates/test_helpers/src/biteq.rs -@@ -53,7 +53,7 @@ macro_rules! impl_float_biteq { - }; - } - --impl_float_biteq! { f16, f32, f64 } -+impl_float_biteq! { f32, f64 } - - impl BitEq for *const T { - fn biteq(&self, other: &Self) -> bool { -diff --git a/crates/test_helpers/src/lib.rs b/crates/test_helpers/src/lib.rs -index 82adb06..4b03674 100644 ---- a/crates/test_helpers/src/lib.rs -+++ b/crates/test_helpers/src/lib.rs -@@ -1,4 +1,3 @@ --#![feature(f16)] - #![cfg_attr( - any(target_arch = "powerpc", target_arch = "powerpc64"), - feature(powerpc_target_feature, stdarch_powerpc) -@@ -47,7 +46,6 @@ impl_num! { u16 } - impl_num! { u32 } - impl_num! { u64 } - impl_num! { usize } --impl_num! { f16 } - impl_num! { f32 } - impl_num! { f64 } - -diff --git a/crates/test_helpers/src/subnormals.rs b/crates/test_helpers/src/subnormals.rs -index 44dfbb3..b5f19ba 100644 ---- a/crates/test_helpers/src/subnormals.rs -+++ b/crates/test_helpers/src/subnormals.rs -@@ -39,7 +39,7 @@ macro_rules! impl_else { - } - } - --impl_float! { f16, f32, f64 } -+impl_float! { f32, f64 } - impl_else! { i8, i16, i32, i64, isize, u8, u16, u32, u64, usize } - - /// AltiVec should flush subnormal inputs to zero, but QEMU seems to only flush outputs. --- -2.53.0 - diff --git a/src/codegen_f16_f128.rs b/src/codegen_f16_f128.rs index 7a386db0cd..00e9555ada 100644 --- a/src/codegen_f16_f128.rs +++ b/src/codegen_f16_f128.rs @@ -174,27 +174,6 @@ pub(crate) fn abs_f128(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value { fx.bcx.ins().bitcast(types::F128, MemFlagsData::new(), bits) } -pub(crate) fn copysign_f16(fx: &mut FunctionCx<'_, '_, '_>, lhs: Value, rhs: Value) -> Value { - let lhs = fx.bcx.ins().bitcast(types::I16, MemFlagsData::new(), lhs); - let rhs = fx.bcx.ins().bitcast(types::I16, MemFlagsData::new(), rhs); - let res = fx.bcx.ins().band_imm(lhs, 0x7fff); - let sign = fx.bcx.ins().band_imm(rhs, 0x8000); - let res = fx.bcx.ins().bor(res, sign); - fx.bcx.ins().bitcast(types::F16, MemFlagsData::new(), res) -} - -pub(crate) fn copysign_f128(fx: &mut FunctionCx<'_, '_, '_>, lhs: Value, rhs: Value) -> Value { - let lhs = fx.bcx.ins().bitcast(types::I128, MemFlagsData::new(), lhs); - let rhs = fx.bcx.ins().bitcast(types::I128, MemFlagsData::new(), rhs); - let (low, lhs_high) = fx.bcx.ins().isplit(lhs); - let (_, rhs_high) = fx.bcx.ins().isplit(rhs); - let high = fx.bcx.ins().band_imm(lhs_high, 0x7fff_ffff_ffff_ffff_u64 as i64); - let sign = fx.bcx.ins().band_imm(rhs_high, 0x8000_0000_0000_0000_u64 as i64); - let high = fx.bcx.ins().bor(high, sign); - let res = fx.bcx.ins().iconcat(low, high); - fx.bcx.ins().bitcast(types::F128, MemFlagsData::new(), res) -} - pub(crate) fn codegen_cast( fx: &mut FunctionCx<'_, '_, '_>, from: Value, diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 292c8004ef..42514daf3c 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -332,7 +332,7 @@ fn codegen_float_intrinsic_call<'tcx>( sym::exp2f64 => ("exp2", 1, fx.tcx.types.f64, types::F64), sym::exp2f128 => ("exp2f128", 1, fx.tcx.types.f128, types::F128), - sym::sqrtf16 => ("sqrtf16", 1, fx.tcx.types.f16, types::F16), + sym::sqrtf16 => return false, // has a fallback via f32 sym::sqrtf32 => ("sqrtf", 1, fx.tcx.types.f32, types::F32), sym::sqrtf64 => ("sqrt", 1, fx.tcx.types.f64, types::F64), sym::sqrtf128 => ("sqrtf128", 1, fx.tcx.types.f128, types::F128), @@ -362,56 +362,58 @@ fn codegen_float_intrinsic_call<'tcx>( sym::log10f64 => ("log10", 1, fx.tcx.types.f64, types::F64), sym::log10f128 => ("log10f128", 1, fx.tcx.types.f128, types::F128), - sym::fmaf16 => ("fmaf16", 3, fx.tcx.types.f16, types::F16), + sym::fmaf16 => return false, // has a fallback via f32 sym::fmaf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), sym::fmaf64 => ("fma", 3, fx.tcx.types.f64, types::F64), sym::fmaf128 => ("fmaf128", 3, fx.tcx.types.f128, types::F128), - // FIXME: calling `fma` from libc without FMA target feature uses expensive sofware emulation - sym::fmuladdf16 => ("fmaf16", 3, fx.tcx.types.f16, types::F16), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f16 - sym::fmuladdf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f32 - sym::fmuladdf64 => ("fma", 3, fx.tcx.types.f64, types::F64), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f64 - sym::fmuladdf128 => ("fmaf128", 3, fx.tcx.types.f128, types::F128), // FIXME: use cranelift intrinsic analogous to llvm.fmuladd.f128 + // FIXME: calling `fma` from libc without FMA target feature uses expensive sofware + // emulation, use cranelift intrinsic analogous to llvm.fmuladd.*. + sym::fmuladdf16 => return false, // has a fallback + sym::fmuladdf32 => ("fmaf", 3, fx.tcx.types.f32, types::F32), + sym::fmuladdf64 => ("fma", 3, fx.tcx.types.f64, types::F64), + sym::fmuladdf128 => return false, // has a fallback - sym::copysignf16 => ("copysignf16", 2, fx.tcx.types.f16, types::F16), + sym::copysignf16 => return false, // has a fallback sym::copysignf32 => ("copysignf", 2, fx.tcx.types.f32, types::F32), sym::copysignf64 => ("copysign", 2, fx.tcx.types.f64, types::F64), - sym::copysignf128 => ("copysignf128", 2, fx.tcx.types.f128, types::F128), + sym::copysignf128 => return false, // has a fallback - sym::floorf16 => ("floorf16", 1, fx.tcx.types.f16, types::F16), + sym::floorf16 => return false, // has a fallback via f32 sym::floorf32 => ("floorf", 1, fx.tcx.types.f32, types::F32), sym::floorf64 => ("floor", 1, fx.tcx.types.f64, types::F64), sym::floorf128 => ("floorf128", 1, fx.tcx.types.f128, types::F128), - sym::ceilf16 => ("ceilf16", 1, fx.tcx.types.f16, types::F16), + sym::ceilf16 => return false, // has a fallback via f32 sym::ceilf32 => ("ceilf", 1, fx.tcx.types.f32, types::F32), sym::ceilf64 => ("ceil", 1, fx.tcx.types.f64, types::F64), sym::ceilf128 => ("ceilf128", 1, fx.tcx.types.f128, types::F128), - sym::truncf16 => ("truncf16", 1, fx.tcx.types.f16, types::F16), + sym::truncf16 => return false, // has a fallback via f32 sym::truncf32 => ("truncf", 1, fx.tcx.types.f32, types::F32), sym::truncf64 => ("trunc", 1, fx.tcx.types.f64, types::F64), sym::truncf128 => ("truncf128", 1, fx.tcx.types.f128, types::F128), - sym::round_ties_even_f16 => ("rintf16", 1, fx.tcx.types.f16, types::F16), + sym::round_ties_even_f16 => return false, // has a fallback via f32 sym::round_ties_even_f32 => ("rintf", 1, fx.tcx.types.f32, types::F32), sym::round_ties_even_f64 => ("rint", 1, fx.tcx.types.f64, types::F64), sym::round_ties_even_f128 => ("rintf128", 1, fx.tcx.types.f128, types::F128), - sym::roundf16 => ("roundf16", 1, fx.tcx.types.f16, types::F16), + sym::roundf16 => return false, // has a fallback via f32 sym::roundf32 => ("roundf", 1, fx.tcx.types.f32, types::F32), sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), sym::roundf128 => ("roundf128", 1, fx.tcx.types.f128, types::F128), - sym::sinf16 => ("sinf16", 1, fx.tcx.types.f16, types::F16), + sym::sinf16 => return false, // has a fallback via f32 sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), sym::sinf128 => ("sinf128", 1, fx.tcx.types.f128, types::F128), - sym::cosf16 => ("cosf16", 1, fx.tcx.types.f16, types::F16), + sym::cosf16 => return false, // has a fallback via f32 sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), sym::cosf64 => ("cos", 1, fx.tcx.types.f64, types::F64), sym::cosf128 => ("cosf128", 1, fx.tcx.types.f128, types::F128), + _ => return false, }; @@ -447,18 +449,9 @@ fn codegen_float_intrinsic_call<'tcx>( // FIXME(bytecodealliance/wasmtime#8312): Use native Cranelift operations // for `f16` and `f128` once the lowerings have been implemented in Cranelift. let res = match intrinsic { - sym::fmaf16 | sym::fmuladdf16 => { - CValue::by_val(codegen_f16_f128::fma_f16(fx, args[0], args[1], args[2]), layout) - } sym::fmaf32 | sym::fmaf64 | sym::fmuladdf32 | sym::fmuladdf64 => { CValue::by_val(fx.bcx.ins().fma(args[0], args[1], args[2]), layout) } - sym::copysignf16 => { - CValue::by_val(codegen_f16_f128::copysign_f16(fx, args[0], args[1]), layout) - } - sym::copysignf128 => { - CValue::by_val(codegen_f16_f128::copysign_f128(fx, args[0], args[1]), layout) - } sym::copysignf32 | sym::copysignf64 => { CValue::by_val(fx.bcx.ins().fcopysign(args[0], args[1]), layout) }