From 45492662c7671e477492eba7c919bc99f7031132 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 24 Feb 2025 21:56:26 +0100 Subject: [PATCH 1/2] correct the docs on `simd_` comparison operators these all also accept integer vectors as arguments --- library/core/src/intrinsics/simd.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 3bde183fefb71..3aec66e9961e5 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -26,28 +26,28 @@ pub unsafe fn simd_extract(_x: T, _idx: u32) -> U; /// Adds two simd vectors elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_add(_x: T, _y: T) -> T; /// Subtracts `rhs` from `lhs` elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_sub(_lhs: T, _rhs: T) -> T; /// Multiplies two simd vectors elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_mul(_x: T, _y: T) -> T; /// Divides `lhs` by `rhs` elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. /// /// # Safety /// For integers, `rhs` must not contain any zero elements. @@ -58,7 +58,7 @@ pub unsafe fn simd_div(_lhs: T, _rhs: T) -> T; /// Returns remainder of two vectors elementwise. /// -/// `T` must be a vector of integer or floating point primitive types. +/// `T` must be a vector of integers or floats. /// /// # Safety /// For integers, `rhs` must not contain any zero elements. @@ -116,8 +116,7 @@ pub unsafe fn simd_xor(_x: T, _y: T) -> T; /// Numerically casts a vector, elementwise. /// -/// `T` and `U` must be vectors of integer or floating point primitive types, and must have the -/// same length. +/// `T` and `U` must be vectors of integers or floats, and must have the same length. /// /// When casting floats to integers, the result is truncated. Out-of-bounds result lead to UB. /// When casting integers to floats, the result is rounded. @@ -138,8 +137,7 @@ pub unsafe fn simd_cast(_x: T) -> U; /// Numerically casts a vector, elementwise. /// -/// `T` and `U` be a vectors of integer or floating point primitive types, and must have the -/// same length. +/// `T` and `U` be a vectors of integers or floats, and must have the same length. /// /// Like `simd_cast`, but saturates float-to-integer conversions (NaN becomes 0). /// This matches regular `as` and is always safe. @@ -187,7 +185,7 @@ pub unsafe fn simd_fmax(_x: T, _y: T) -> T; /// Tests elementwise equality of two vectors. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -198,7 +196,7 @@ pub unsafe fn simd_eq(_x: T, _y: T) -> U; /// Tests elementwise inequality equality of two vectors. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -209,7 +207,7 @@ pub unsafe fn simd_ne(_x: T, _y: T) -> U; /// Tests if `x` is less than `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -220,7 +218,7 @@ pub unsafe fn simd_lt(_x: T, _y: T) -> U; /// Tests if `x` is less than or equal to `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -231,7 +229,7 @@ pub unsafe fn simd_le(_x: T, _y: T) -> U; /// Tests if `x` is greater than `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -242,7 +240,7 @@ pub unsafe fn simd_gt(_x: T, _y: T) -> U; /// Tests if `x` is greater than or equal to `y`, elementwise. /// -/// `T` must be a vector of floating-point primitive types. +/// `T` must be a vector of integer or floating-point primitive types. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// From 854e9f48033e2cfe8615ed3b24ceccb137addd46 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Fri, 28 Feb 2025 22:46:54 +0100 Subject: [PATCH 2/2] intrinsics::simd: document that masks must be signed integer vectors this is because they may be widened, and that only works when sign extension is used: zero extension would produce invalid results --- library/core/src/intrinsics/simd.rs | 54 ++++++++++++++--------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs index 3aec66e9961e5..cceb6b0917afa 100644 --- a/library/core/src/intrinsics/simd.rs +++ b/library/core/src/intrinsics/simd.rs @@ -71,7 +71,7 @@ pub unsafe fn simd_rem(_lhs: T, _rhs: T) -> T; /// /// Shifts `lhs` left by `rhs`, shifting in sign bits for signed types. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. /// /// # Safety /// @@ -82,7 +82,7 @@ pub unsafe fn simd_shl(_lhs: T, _rhs: T) -> T; /// Shifts vector right elementwise, with UB on overflow. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. /// /// Shifts `lhs` right by `rhs`, shifting in sign bits for signed types. /// @@ -95,21 +95,21 @@ pub unsafe fn simd_shr(_lhs: T, _rhs: T) -> T; /// "Ands" vectors elementwise. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_and(_x: T, _y: T) -> T; /// "Ors" vectors elementwise. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_or(_x: T, _y: T) -> T; /// "Exclusive ors" vectors elementwise. /// -/// `T` must be a vector of integer primitive types. +/// `T` must be a vector of integers. #[rustc_intrinsic] #[rustc_nounwind] pub unsafe fn simd_xor(_x: T, _y: T) -> T; @@ -151,7 +151,7 @@ pub unsafe fn simd_as(_x: T) -> U; /// Negates a vector elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// Rust panics for `-::Min` due to overflow, but it is not UB with this intrinsic. #[rustc_intrinsic] @@ -185,7 +185,7 @@ pub unsafe fn simd_fmax(_x: T, _y: T) -> T; /// Tests elementwise equality of two vectors. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -196,7 +196,7 @@ pub unsafe fn simd_eq(_x: T, _y: T) -> U; /// Tests elementwise inequality equality of two vectors. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -207,7 +207,7 @@ pub unsafe fn simd_ne(_x: T, _y: T) -> U; /// Tests if `x` is less than `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -218,7 +218,7 @@ pub unsafe fn simd_lt(_x: T, _y: T) -> U; /// Tests if `x` is less than or equal to `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -229,7 +229,7 @@ pub unsafe fn simd_le(_x: T, _y: T) -> U; /// Tests if `x` is greater than `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -240,7 +240,7 @@ pub unsafe fn simd_gt(_x: T, _y: T) -> U; /// Tests if `x` is greater than or equal to `y`, elementwise. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be a vector of integers with the same number of elements and element size as `T`. /// @@ -271,7 +271,7 @@ pub unsafe fn simd_shuffle(_x: T, _y: T, _idx: U) -> V; /// /// `U` must be a vector of pointers to the element type of `T`, with the same length as `T`. /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, read the pointer. /// Otherwise if the corresponding value in `mask` is `0`, return the corresponding value from @@ -292,7 +292,7 @@ pub unsafe fn simd_gather(_val: T, _ptr: U, _mask: V) -> T; /// /// `U` must be a vector of pointers to the element type of `T`, with the same length as `T`. /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each pointer in `ptr`, if the corresponding value in `mask` is `!0`, write the /// corresponding value in `val` to the pointer. @@ -316,7 +316,7 @@ pub unsafe fn simd_scatter(_val: T, _ptr: U, _mask: V); /// /// `U` must be a pointer to the element type of `T` /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each element, if the corresponding value in `mask` is `!0`, read the corresponding /// pointer offset from `ptr`. @@ -339,7 +339,7 @@ pub unsafe fn simd_masked_load(_mask: V, _ptr: U, _val: T) -> T; /// /// `U` must be a pointer to the element type of `T` /// -/// `V` must be a vector of integers with the same length as `T` (but any element size). +/// `V` must be a vector of signed integers with the same length as `T` (but any element size). /// /// For each element, if the corresponding value in `mask` is `!0`, write the corresponding /// value in `val` to the pointer offset from `ptr`. @@ -373,7 +373,7 @@ pub unsafe fn simd_saturating_sub(_lhs: T, _rhs: T) -> T; /// Adds elements within a vector from left to right. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -385,7 +385,7 @@ pub unsafe fn simd_reduce_add_ordered(_x: T, _y: U) -> U; /// Adds elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -394,7 +394,7 @@ pub unsafe fn simd_reduce_add_unordered(_x: T) -> U; /// Multiplies elements within a vector from left to right. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -406,7 +406,7 @@ pub unsafe fn simd_reduce_mul_ordered(_x: T, _y: U) -> U; /// Multiplies elements within a vector in arbitrary order. May also be re-associated with /// unordered additions on the inputs/outputs. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -435,7 +435,7 @@ pub unsafe fn simd_reduce_any(_x: T) -> bool; /// Returns the maximum element of a vector. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -446,7 +446,7 @@ pub unsafe fn simd_reduce_max(_x: T) -> U; /// Returns the minimum element of a vector. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. /// @@ -457,7 +457,7 @@ pub unsafe fn simd_reduce_min(_x: T) -> U; /// Logical "ands" all elements together. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -466,7 +466,7 @@ pub unsafe fn simd_reduce_and(_x: T) -> U; /// Logical "ors" all elements together. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -475,7 +475,7 @@ pub unsafe fn simd_reduce_or(_x: T) -> U; /// Logical "exclusive ors" all elements together. /// -/// `T` must be a vector of integer or floating-point primitive types. +/// `T` must be a vector of integers or floats. /// /// `U` must be the element type of `T`. #[rustc_intrinsic] @@ -521,9 +521,9 @@ pub unsafe fn simd_bitmask(_x: T) -> U; /// Selects elements from a mask. /// -/// `M` must be an integer vector. +/// `T` must be a vector. /// -/// `T` must be a vector with the same number of elements as `M`. +/// `M` must be a signed integer vector with the same length as `T` (but any element size). /// /// For each element, if the corresponding value in `mask` is `!0`, select the element from /// `if_true`. If the corresponding value in `mask` is `0`, select the element from