about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-06-29 12:29:53 +0200
committerGitHub <noreply@github.com>2025-06-29 12:29:53 +0200
commit66ad1f2abf648ba0644cd478dd49cde0f4bef558 (patch)
tree58ba7b22c77dbca08839f920313a2e28ef58175a /library/core/src
parent5ca574e85b67cec0a6fc3fddfe398cbe676c9c69 (diff)
parent2ffa1dd392c1fe9c23a2f11f7b7a293a744c05ce (diff)
Rollup merge of #142078 - sayantn:more-intrinsics, r=workingjubilee
Add SIMD funnel shift and round-to-even intrinsics

This PR adds 3 new SIMD intrinsics

 - `simd_funnel_shl` - funnel shift left
 - `simd_funnel_shr` - funnel shift right
 - `simd_round_ties_even` (vector version of `round_ties_even_fN`)

TODO (future PR): implement `simd_fsh{l,r}` in miri, cg_gcc and cg_clif (it is surprisingly hard to implement without branches, the common tricks that rotate uses doesn't work because we have 2 elements now. e.g, the `-n&31` trick used by cg_gcc to implement rotate doesn't work with this because then `fshl(a, b, 0)` will be `a | b`)

[#t-compiler > More SIMD intrinsics](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/More.20SIMD.20intrinsics/with/522130286)

`@rustbot` label T-compiler T-libs A-intrinsics F-core_intrinsics
r? `@workingjubilee`
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/intrinsics/simd.rs42
1 files changed, 42 insertions, 0 deletions
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index 40efc263068..11533ab6aa4 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -126,6 +126,40 @@ pub unsafe fn simd_shl<T>(lhs: T, rhs: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn simd_shr<T>(lhs: T, rhs: T) -> T;
 
+/// Funnel Shifts vector left elementwise, with UB on overflow.
+///
+/// Concatenates `a` and `b` elementwise (with `a` in the most significant half),
+/// creating a vector of the same length, but with each element being twice as
+/// wide. Then shift this vector left elementwise by `shift`, shifting in zeros,
+/// and extract the most significant half of each of the elements. If `a` and `b`
+/// are the same, this is equivalent to an elementwise rotate left operation.
+///
+/// `T` must be a vector of integers.
+///
+/// # Safety
+///
+/// Each element of `shift` must be less than `<int>::BITS`.
+#[rustc_intrinsic]
+#[rustc_nounwind]
+pub unsafe fn simd_funnel_shl<T>(a: T, b: T, shift: T) -> T;
+
+/// Funnel Shifts vector right elementwise, with UB on overflow.
+///
+/// Concatenates `a` and `b` elementwise (with `a` in the most significant half),
+/// creating a vector of the same length, but with each element being twice as
+/// wide. Then shift this vector right elementwise by `shift`, shifting in zeros,
+/// and extract the least significant half of each of the elements. If `a` and `b`
+/// are the same, this is equivalent to an elementwise rotate right operation.
+///
+/// `T` must be a vector of integers.
+///
+/// # Safety
+///
+/// Each element of `shift` must be less than `<int>::BITS`.
+#[rustc_intrinsic]
+#[rustc_nounwind]
+pub unsafe fn simd_funnel_shr<T>(a: T, b: T, shift: T) -> T;
+
 /// "Ands" vectors elementwise.
 ///
 /// `T` must be a vector of integers.
@@ -678,6 +712,14 @@ pub unsafe fn simd_floor<T>(x: T) -> T;
 #[rustc_nounwind]
 pub unsafe fn simd_round<T>(x: T) -> T;
 
+/// Rounds each element to the closest integer-valued float.
+/// Ties are resolved by rounding to the number with an even least significant digit
+///
+/// `T` must be a vector of floats.
+#[rustc_intrinsic]
+#[rustc_nounwind]
+pub unsafe fn simd_round_ties_even<T>(x: T) -> T;
+
 /// Returns the integer part of each element as an integer-valued float.
 /// In other words, non-integer values are truncated towards zero.
 ///