Skip to content

Commit 51e9b40

Browse files
authored
Rollup merge of rust-lang#137447 - folkertdev:simd-extract-insert-dyn, r=scottmcm
add `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}` fixes rust-lang#137372 adds `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`, which contrary to their non-dyn counterparts allow a non-const index. Many platforms (but notably not x86_64 or aarch64) have dedicated instructions for this operation, which stdarch can emit with this change. Future work is to also make the `Index` operation on the `Simd` type emit this operation, but the intrinsic can't be used directly. We'll need some MIR shenanigans for that. r? `@ghost`
2 parents df8d99a + e017596 commit 51e9b40

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

Diff for: core/src/intrinsics/simd.rs

+36-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
/// Inserts an element into a vector, returning the updated vector.
66
///
7-
/// `T` must be a vector with element type `U`.
7+
/// `T` must be a vector with element type `U`, and `idx` must be `const`.
88
///
99
/// # Safety
1010
///
@@ -15,15 +15,48 @@ pub const unsafe fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
1515

1616
/// Extracts an element from a vector.
1717
///
18-
/// `T` must be a vector with element type `U`.
18+
/// `T` must be a vector with element type `U`, and `idx` must be `const`.
1919
///
2020
/// # Safety
2121
///
22-
/// `idx` must be in-bounds of the vector.
22+
/// `idx` must be const and in-bounds of the vector.
2323
#[rustc_intrinsic]
2424
#[rustc_nounwind]
2525
pub const unsafe fn simd_extract<T, U>(x: T, idx: u32) -> U;
2626

27+
/// Inserts an element into a vector, returning the updated vector.
28+
///
29+
/// `T` must be a vector with element type `U`.
30+
///
31+
/// If the index is `const`, [`simd_insert`] may emit better assembly.
32+
///
33+
/// # Safety
34+
///
35+
/// `idx` must be in-bounds of the vector.
36+
#[rustc_nounwind]
37+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
38+
pub unsafe fn simd_insert_dyn<T, U>(mut x: T, idx: u32, val: U) -> T {
39+
// SAFETY: `idx` must be in-bounds
40+
unsafe { (&raw mut x).cast::<U>().add(idx as usize).write(val) }
41+
x
42+
}
43+
44+
/// Extracts an element from a vector.
45+
///
46+
/// `T` must be a vector with element type `U`.
47+
///
48+
/// If the index is `const`, [`simd_extract`] may emit better assembly.
49+
///
50+
/// # Safety
51+
///
52+
/// `idx` must be in-bounds of the vector.
53+
#[rustc_nounwind]
54+
#[cfg_attr(not(bootstrap), rustc_intrinsic)]
55+
pub unsafe fn simd_extract_dyn<T, U>(x: T, idx: u32) -> U {
56+
// SAFETY: `idx` must be in-bounds
57+
unsafe { (&raw const x).cast::<U>().add(idx as usize).read() }
58+
}
59+
2760
/// Adds two simd vectors elementwise.
2861
///
2962
/// `T` must be a vector of integers or floats.

0 commit comments

Comments
 (0)