safe_unaligned_simd
Safe wrappers for unaligned SIMD load and store operations.
The goal of this crate is to remove the need for "unnecessary unsafe" code when using vector intrinsics to access memory, with no alignment requirements.
Platform-intrinsics that take raw pointers have been wrapped in functions that receive Rust reference types as arguments.
MSRV: 1.88
Why use this crate?
This crate is compatible with runtime feature detection.
Unlike some other safe architecture intrinsic wrappers, this crate does not lock the user into #[cfg()]-gating SIMD code behind compile-time CPU target feature declaration.
[!NOTE]
To safely use platform intrinsics, users are responsible for ensuring that the CPU supports the intended target feature.Feature detection can be done at compile-time by using
#[cfg]attributes on functions or at runtime using anis_[arch]_feature_detected!macro fromstd::arch.
unsafeis needed to call into functions annotated with#[target_feature], but it's safe to call other functions with the same target features.See the
std::archmodule documentation for a full explanation and therustc1.87 release notes for a simple example of runtime feature detection with fallback.
Supported target architectures
x86 / x86_64
sse,sse2,avx,avx512f,avx512vl,avx512bw,avx512vbmi2
Some functions have variants that are generic over Cell array types, which allow for mutation of shared references.
See the cell module for an example.
Example function signatures:
;
;
;
Currently, there is no plan to implement gather/scatter or avx2 masked load/store intrinsics for this platform.
avx512 - AVX-512 intrinsics require rustc 1.89 or later.
aarch64 / arm64ec
neon
Example function signatures:
;
;
wasm32
simd128
Example function signatures:
;
;
A note on creating mutable array references from slices
tl;dr: Use as_mut_array to avoid this bug, stable since 1.93.
Beware of accidentally creating mutable references to temporary arrays.
Rust will implicitly clone an array from a slice and return a mutable reference to that clone if not wrapped properly in parentheses.
// Valid mutable array reference creation
let out_data: &mut = chunk.as_mut_array.unwrap; // since 1.93
let out_data: &mut = .try_into.unwrap;
let out_data = try_into.unwrap;
// Incorrect creation of a mutable reference: this clones the chunk and returns
// a mutable reference to the copy. If we modify `out_data` after this point,
// the changes will not reflect back in our original `chunk` slice.
// 🚫🈲⛔❌ - Do not use the following line
let out_data = &mut chunk.try_into.unwrap;
The now-stable as_mut_array sidesteps this issue entirely.
License
This crate is licensed under either
- the MIT License, or
- the Apache License (Version 2.0)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.