Parts of this implementation are already integrated into GCC 16. If you want to try the development version you can either install this library via:
make prefix=~/.local installor simply point your compiler's include path to this repository.
Alternatively you can also install into the compiler's standard library directory:
make install-systemThere is no support for uninstalling, since install-system overwrites the std::simd headers of libstdc++.
Build your own project with C++26 (latest GCC, PRs to support Clang are
welcome). Just include <simd> and you're good to go:
#include <simd>To build the tests there are multiple targets available. make help will list all of them.
By default all vectorizable types (including complex) are supported. More features can be enabled by defining the following macros:
| Macro | Description |
|---|---|
VIR_EXTENSIONS |
Enable several optimizations and warnings on guaranteed precondition violations. |
VIR_PATCH_PERMUTE_DYNAMIC |
Implements [simd.permute.dynamic]. |
VIR_PATCH_MATH |
Implements [simd.math]. |
VIR_PATCH_IMPROVE_CX |
Implements abs and norm for vec<complex<T>>. Three different approaches =1, =2, and =3 make different optimization/code-gen trade-offs. |
VIR_PATCH_MISSED_OPT |
Enable hand-written instruction selection for optimization patterns the compiler misses. Includes ktest-based mask reductions and pshufb-based type conversions on x86. |
VIR_PATCH_TEST_STORES |
Fix masked stores. |
VIR_CONSTEVAL_BROADCAST |
Use consteval broadcast constructor for value-preserving conversions: Either the value doesn't change or the program is ill-formed. Peace of mind. |
| Feature | Status |
|---|---|
| P1928R15 std::simd — merge data-parallel types from the Parallelism TS 2 | ✅ done (except math) |
| P2663R7 Interleaved complex values support in std::simd | ✅ done (except math) |
| P2664R11 Proposal to extend std::simd with permutation API | 🟡 partial |
| P2876R3 Proposal to extend std::simd with more constructors and accessors | ✅ done |
| P2929R2 simd_invoke | 🔴 open (still in design phase) |
| P2933R4 Extend ⟨bit⟩ header function with overloads for std::simd | ✅ done |
P2933R4 std::simd overloads for <bit> header |
✅ done (not optimized) |
| P2964R2 Allowing user-defined types in std::simd | 🔴 open (still in design phase) |
| P3287R3 Exploration of namespaces for std::simd | ✅ done |
| P3430R3 simd issues: explicit, unsequenced, identity-element position, and members of disabled simd | ✅ done |
| P3440R2 Add n_elements named constructor to std::simd | 🔴 open (still in design phase) |
| P3441R2 Rename simd_split to simd_chunk | ✅ done |
| P3480R6 std::simd is a range | ✅ done |
| P3691R1 Reconsider naming of the namespace for 'std::simd' | ✅ done |
| P3844R4 Reword [simd.math] for consteval conversions | ✅ done |
| P3932R0 Fix LWG4470: Fix integer-from in [simd] | ✅ done |
| P3973R0 bit_cast_as: Element type reinterpretation for std::simd | 🔴 open (still in design phase) |
| P3983R0 simd object representation | 🔴 open (still in design phase) |
| P3985R0 Concepts for std::simd | 🔴 open (still in design phase) |
| P4012R1 value-preserving consteval broadcast to simd::vec | ✅ done |
P4042R0 Fix LWG4543: incorrect cast between simd::vec and simd::mask via conversion to and from impl-defined vector types |
✅ done |
| Issue | Status |
|---|---|
LWG4230 simd<complex>::real/imag is overconstrained |
✅ done |
LWG4231 datapar::chunk<N> should use simd-size-type instead of size_t |
✅ done |
LWG4232 datapar::resize does not resize |
✅ done |
LWG4238 simd_mask<complex<double>>::operator+/-/~ return a disabled simd specialization |
✅ done |
LWG4280 simd::partial_load uses undefined identifier T |
🔴 unclear |
LWG4375 std::simd::bit_ceil should not be noexcept |
🔴 unclear |
| LWG4376 ABI tag in return type of [simd.mask.unary] is overconstrained | ✅ done |
LWG4382 The simd::basic_mask(bool) overload needs to be more constrained |
🔴 unclear |
LWG4385 Including <simd> doesn't provide std::begin/end |
✅ done (via inclusion of <span>) |
LWG4386 std::simd::select(bool c, const T& a, const U& b) is underconstrained |
🔴 unclear |
LWG4390 simd::basic_vec(U&&) default template parameter |
⚪ treated as NAD |
LWG4391 Ambiguities of simd::basic_vec constructor |
🔴 unclear |
LWG4392 simd::unchecked_load misses difference type casting |
🔴 unclear |
LWG4393 simd::unchecked_scatter_to is underconstrained |
🔴 unclear |
LWG4394 simd::unchecked_load(I first, S last) construct span maybe ill-formed |
🔴 unclear |
| LWG4402 List-initialization of iterators in [simd.mask.overview] | 🔴 unclear |
LWG4403 simd::basic_vec CTAD misses difference type casting |
✅ done |
LWG4407 constexpr-wrapper-like needs remove_cvref_t in simd::basic_vec constructor |
✅ done |
LWG4408 Hardening simd::vec::operator[] |
🔴 unclear |
LWG4409 Constant expression ranges::size(r) Constraints and Mandates in [simd] |
🔴 open |
LWG4412 Fix declaration of zero_element and uninit_element |
✅ done |
LWG4413 Unused/left-over simd::alignment specialization for basic_mask |
✅ done |
LWG4414 §[simd.expos.abi] deduce-abi-t is underspecified and incorrectly referenced from rebind and resize |
✅ done (P3932R0) |
LWG4420 §[simd] conversions (constructor, load, stores, gather, and scatter) are incorrectly constrained for <stdfloat> types |
✅ done |
LWG4436 simd broadcast is overconstrained — std::cw<0.f> is not convertible to simd::vec<float16_t> |
🔴 unclear |
LWG4470 The use of integer-from<Bytes> all over [simd] is incorrect for Bytes=sizeof(complex<double>) |
✅ done (P3932R0) |
LWG4518 simd::cat return type requires inefficient ABI tag change/conversion |
✅ done (P3932R0) |
LWG4535 Disallow user specialization of <simd> templates |
✅ done (not actionable) |
LWG4543 Incorrect cast between simd::vec and simd::mask via conversion to and from impl-defined vector types |
✅ done (P4042R0) |