diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index a5334afbe5f8b..cb5d54020f7fc 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -400,7 +400,15 @@ where if min_index.eq(T::TRUE) { None } else { - Some(min_index.to_usize()) + let min_index = min_index.to_usize(); + + // Allow eliminating bounds checks when using the index + // Safety: the index can't exceed the number of elements in the vector + unsafe { + core::hint::assert_unchecked(min_index < N); + } + + Some(min_index) } } } 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 510f4c9eea393..14a31b527872b 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 @@ -430,14 +430,14 @@ macro_rules! impl_trait { #[inline] fn reduce_max(self) -> Self::Scalar { - // Safety: `self` is a float vector - unsafe { core::intrinsics::simd::simd_reduce_max(self) } + // LLVM has no intrinsic we can use here + // (https://github.com/llvm/llvm-project/issues/185827). + self.as_array().iter().copied().fold(Self::Scalar::NAN, Self::Scalar::max) } #[inline] fn reduce_min(self) -> Self::Scalar { - // Safety: `self` is a float vector - unsafe { core::intrinsics::simd::simd_reduce_min(self) } + self.as_array().iter().copied().fold(Self::Scalar::NAN, Self::Scalar::min) } } )* diff --git a/library/portable-simd/crates/core_simd/src/simd/prelude.rs b/library/portable-simd/crates/core_simd/src/simd/prelude.rs index 6e93f16e10b1c..51b8def3d6eed 100644 --- a/library/portable-simd/crates/core_simd/src/simd/prelude.rs +++ b/library/portable-simd/crates/core_simd/src/simd/prelude.rs @@ -14,6 +14,10 @@ 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/library/portable-simd/crates/std_float/tests/float.rs b/library/portable-simd/crates/std_float/tests/float.rs index 0fa5da3dca506..f97e1123c8527 100644 --- a/library/portable-simd/crates/std_float/tests/float.rs +++ b/library/portable-simd/crates/std_float/tests/float.rs @@ -33,23 +33,6 @@ macro_rules! unary_approx_test { } } -macro_rules! binary_approx_test { - { $scalar:tt, $($func:tt),+ } => { - test_helpers::test_lanes! { - $( - fn $func() { - test_helpers::test_binary_elementwise_approx( - &core_simd::simd::Simd::<$scalar, LANES>::$func, - &$scalar::$func, - &|_, _| true, - 16, - ) - } - )* - } - } -} - macro_rules! ternary_test { { $scalar:tt, $($func:tt),+ } => { test_helpers::test_lanes! { @@ -76,7 +59,19 @@ macro_rules! impl_tests { // https://github.com/rust-lang/miri/issues/3555 unary_approx_test! { $scalar, sin, cos, exp, exp2, ln, log2, log10 } - binary_approx_test! { $scalar, log } + + // The implementation of log is a.ln() / b.ln(), so there are 2 inexact operations, + // hence a larger ulps is needed. + test_helpers::test_lanes! { + fn log() { + test_helpers::test_binary_elementwise_approx( + &core_simd::simd::Simd::<$scalar, LANES>::log, + &$scalar::log, + &|_, _| true, + 32, + ) + } + } test_helpers::test_lanes! { fn fract() { diff --git a/library/portable-simd/crates/test_helpers/src/lib.rs b/library/portable-simd/crates/test_helpers/src/lib.rs index 82adb06d8a9d4..ce3680ac2c306 100644 --- a/library/portable-simd/crates/test_helpers/src/lib.rs +++ b/library/portable-simd/crates/test_helpers/src/lib.rs @@ -122,12 +122,23 @@ pub fn make_runner() -> proptest::test_runner::TestRunner { proptest::test_runner::TestRunner::new(proptest::test_runner::Config::with_cases(4)) } +#[track_caller] +fn unwrap_test_error( + x: Result>, +) -> T { + // Using the `Display` instance of the error is much more readable. + match x { + Ok(v) => v, + Err(e) => panic!("{e}"), + } +} + /// Test a function that takes a single value. pub fn test_1( f: &dyn Fn(A) -> proptest::test_runner::TestCaseResult, ) { let mut runner = make_runner(); - runner.run(&A::default_strategy(), f).unwrap(); + unwrap_test_error(runner.run(&A::default_strategy(), f)) } /// Test a function that takes two values. @@ -135,11 +146,11 @@ pub fn test_2 proptest::test_runner::TestCaseResult, ) { let mut runner = make_runner(); - runner - .run(&(A::default_strategy(), B::default_strategy()), |(a, b)| { + unwrap_test_error( + runner.run(&(A::default_strategy(), B::default_strategy()), |(a, b)| { f(a, b) - }) - .unwrap(); + }), + ) } /// Test a function that takes two values. @@ -151,16 +162,14 @@ pub fn test_3< f: &dyn Fn(A, B, C) -> proptest::test_runner::TestCaseResult, ) { let mut runner = make_runner(); - runner - .run( - &( - A::default_strategy(), - B::default_strategy(), - C::default_strategy(), - ), - |(a, b, c)| f(a, b, c), - ) - .unwrap(); + unwrap_test_error(runner.run( + &( + A::default_strategy(), + B::default_strategy(), + C::default_strategy(), + ), + |(a, b, c)| f(a, b, c), + )); } /// Test a unary vector function against a unary scalar function, applied elementwise. diff --git a/library/portable-simd/rust-toolchain.toml b/library/portable-simd/rust-toolchain.toml index 6a58e59fb93ef..27d2dd6efbbb8 100644 --- a/library/portable-simd/rust-toolchain.toml +++ b/library/portable-simd/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2026-03-18" +channel = "nightly-2026-04-28" components = ["rustfmt", "clippy", "miri", "rust-src"]