[PATCH v6] libstdc++: Implement [simd] for C++26
Matthias Kretz
MatthiasKretz@gmx.net
Fri Mar 20 23:03:27 GMT 2026
Tested on x86_64-pc-linux-gnu (with expensive tests enabled).
Changes since v5:
- #ifdef math_errhandling
- Replace … with [...]
- Implement LWG4412 (inline instead of static for std::simd::zero_element and
uninit_element)
- Use std::__conditional_t. I don't care for the mangling anywhere, but I care
a lot for compile time performance.
- Replace <tt> with backticks in comments.
- Replace \ with @ in doxygen commands.
- Fix the "value-reserving" typo.
- Squash (adjusted) https://forge.sourceware.org/mkretz/gcc/pulls/1/commits/
41d37c3bfdd521a864b007ebba63c8c52ca4015a to make default tests cheaper.
Also visible on the Forge as
- https://forge.sourceware.org/gcc/gcc-TEST/commit/
0ab5a8e005ba267001c22da922786b768e5ba67b
- https://forge.sourceware.org/gcc/gcc-TEST/commit/
bef1fb214620ce9b1a0177934318f23b5fa34003
- https://forge.sourceware.org/gcc/gcc-TEST/compare/
bef1fb214620ce9b1a0177934318f23b5fa34003..bd634e7ad5451211ade86a25621c57432ea48122
Replies (no further changes):
> >+#define _GLIBCXX_SIMD_TOSTRING_IMPL(x) #x
> >+#define _GLIBCXX_SIMD_TOSTRING(x) _GLIBCXX_SIMD_TOSTRING_IMPL(x)
>
> Will this be able to use reflection some day? 🙂
It's actually unused in this patch and the next (simd.complex). I use it for
my "warning on precondition violation" macro and in simd_math.h. It's probably
better if I drop it until then?
And, at least for the precondition macro it needs to use "string " "concat "
"like so", because I need a string literal for the [[gnu::warning]] attribute.
Reflection won't give me literals, right? :)
> >+ [[__gnu__::__always_inline__]]
> >+ friend constexpr bool
> >+ __is_const_known(const basic_vec& __x)
> >+ { return __builtin_constant_p(__x._M_data); }
>
> Is there any compilation speed benefit to using if consteval here for
> the 1-arg case, or is that only an advantage when it prevents the
> recursion?
That's a good question. Possibly yes, but I would assume the
__builtin_constant_p isn't very expensive either. The multi-arg
__is_const_known overload uses the shortcut mostly to avoid recursing into
more of these functions.
------------ 8< ------------
This implementation differs significantly from the
std::experimental::simd implementation. One goal was a reduction in
template instantiations wrt. what std::experimental::simd did.
Design notes:
- bits/vec_ops.h contains concepts, traits, and functions for working
with GNU vector builtins that are mostly independent from std::simd.
These could move from std::simd:: to std::__vec (or similar). However,
we would then need to revisit naming. For now we kept everything in
the std::simd namespace with __vec_ prefix in the names. The __vec_*
functions can be called unqualified because they can never be called
on user-defined types (no ADL). If we ever get simd<UDT> support this
will be implemented via bit_cast to/from integral vector
builtins/intrinsics.
- bits/simd_x86.h extends vec_ops.h with calls to __builtin_ia32_* that
can only be used after uttering the right GCC target pragma.
- basic_vec and basic_mask are built on top of register-size GNU vector
builtins (for now / x86). Any larger vec/mask is a tree of power-of-2
#elements on the "first" branch. Anything non-power-of-2 that is
smaller than register size uses padding elements that participate in
element-wise operations. The library ensures that padding elements
lead to no side effects. The implementation makes no assumption on the
values of these padding elements since the user can bit_cast to
basic_vec/basic_mask.
Implementation status:
- The implementation is prepared for more than x86 but is x86-only for
now.
- Parts of [simd] *not* implemented in this patch:
- std::complex<floating-point> as vectorizable types
- [simd.permute.dynamic]
- [simd.permute.mask]
- [simd.permute.memory]
- [simd.bit]
- [simd.math]
- mixed operations with vec-mask and bit-mask types
- some conversion optimizations (open questions wrt. missed
optimizations in the compiler)
- This patch implements P3844R3 "Restore simd::vec broadcast from int",
which is not part of the C++26 WD draft yet. If the paper does not get
accepted the feature will be reverted.
- This patch implements D4042R0 "incorrect cast between simd::vec and
simd::mask via conversion to and from impl-defined vector types" (to be
published once the reported LWG issue gets a number).
- The standard feature test macro __cpp_lib_simd is not defined yet.
Tests:
- Full coverage requires testing
1. constexpr,
2. constant-propagating inputs, and
3. unknown (to the optimizer) inputs
- for all vectorizable types
* for every supported width (1–64 and higher)
+ for all possible ISA extensions (combinations)
= with different fast-math flags
... leading to a test matrix that's far out of reach for regular
testsuite builds.
- The tests in testsuite/std/simd/ try to cover all of the API. The
tests can be build in every combination listed above. Per default only
a small subset is built and tested.
- Use GCC_TEST_RUN_EXPENSIVE=something to compile the more expensive
tests (constexpr and const-prop testing) and to enable more /
different widths for the test type.
- Tests can still emit bogus -Wpsabi warnings (see PR98734) which are
filtered out via dg-prune-output.
Benchmarks:
- The current implementation has been benchmarked in some aspects on
x86_64 hardware. There is more optimization potential. However, it is
not always clear whether optimizations should be part of the library
if they can be implemented in the compiler.
- No benchmark code is included in this patch.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Add simd headers.
* include/Makefile.in: Regenerate.
* include/bits/version.def (simd): New.
* include/bits/version.h: Regenerate.
* include/bits/simd_alg.h: New file.
* include/bits/simd_details.h: New file.
* include/bits/simd_flags.h: New file.
* include/bits/simd_iterator.h: New file.
* include/bits/simd_loadstore.h: New file.
* include/bits/simd_mask.h: New file.
* include/bits/simd_mask_reductions.h: New file.
* include/bits/simd_reductions.h: New file.
* include/bits/simd_vec.h: New file.
* include/bits/simd_x86.h: New file.
* include/bits/vec_ops.h: New file.
* include/std/simd: New file.
* testsuite/std/simd/arithmetic.cc: New test.
* testsuite/std/simd/arithmetic_expensive.cc: New test.
* testsuite/std/simd/create_tests.h: New file.
* testsuite/std/simd/creation.cc: New test.
* testsuite/std/simd/creation_expensive.cc: New test.
* testsuite/std/simd/loads.cc: New test.
* testsuite/std/simd/loads_expensive.cc: New test.
* testsuite/std/simd/mask2.cc: New test.
* testsuite/std/simd/mask2_expensive.cc: New test.
* testsuite/std/simd/mask.cc: New test.
* testsuite/std/simd/mask_expensive.cc: New test.
* testsuite/std/simd/reductions.cc: New test.
* testsuite/std/simd/reductions_expensive.cc: New test.
* testsuite/std/simd/shift_left.cc: New test.
* testsuite/std/simd/shift_left_expensive.cc: New test.
* testsuite/std/simd/shift_right.cc: New test.
* testsuite/std/simd/shift_right_expensive.cc: New test.
* testsuite/std/simd/simd_alg.cc: New test.
* testsuite/std/simd/simd_alg_expensive.cc: New test.
* testsuite/std/simd/sse_intrin.cc: New test.
* testsuite/std/simd/stores.cc: New test.
* testsuite/std/simd/stores_expensive.cc: New test.
* testsuite/std/simd/test_setup.h: New file.
* testsuite/std/simd/traits_common.cc: New test.
* testsuite/std/simd/traits_impl.cc: New test.
* testsuite/std/simd/traits_math.cc: New test.
libstdc++-v3/include/Makefile.am | 12 +
libstdc++-v3/include/Makefile.in | 12 +
libstdc++-v3/include/bits/simd_alg.h | 98 +
libstdc++-v3/include/bits/simd_details.h | 1394 ++++++++++
libstdc++-v3/include/bits/simd_flags.h | 187 ++
libstdc++-v3/include/bits/simd_iterator.h | 177 ++
libstdc++-v3/include/bits/simd_loadstore.h | 408 +++
libstdc++-v3/include/bits/simd_mask.h | 1972 ++++++++++++++
.../include/bits/simd_mask_reductions.h | 118 +
libstdc++-v3/include/bits/simd_reductions.h | 109 +
libstdc++-v3/include/bits/simd_vec.h | 2297 +++++++++++++++++
libstdc++-v3/include/bits/simd_x86.h | 1413 ++++++++++
libstdc++-v3/include/bits/vec_ops.h | 606 +++++
libstdc++-v3/include/bits/version.def | 13 +
libstdc++-v3/include/bits/version.h | 9 +
libstdc++-v3/include/std/simd | 48 +
libstdc++-v3/testsuite/std/simd/arithmetic.cc | 329 +++
.../std/simd/arithmetic_expensive.cc | 7 +
.../testsuite/std/simd/create_tests.h | 15 +
libstdc++-v3/testsuite/std/simd/creation.cc | 69 +
.../testsuite/std/simd/creation_expensive.cc | 7 +
libstdc++-v3/testsuite/std/simd/loads.cc | 121 +
.../testsuite/std/simd/loads_expensive.cc | 7 +
libstdc++-v3/testsuite/std/simd/mask.cc | 112 +
libstdc++-v3/testsuite/std/simd/mask2.cc | 108 +
.../testsuite/std/simd/mask2_expensive.cc | 7 +
.../testsuite/std/simd/mask_expensive.cc | 7 +
libstdc++-v3/testsuite/std/simd/reductions.cc | 90 +
.../std/simd/reductions_expensive.cc | 7 +
libstdc++-v3/testsuite/std/simd/shift_left.cc | 67 +
.../std/simd/shift_left_expensive.cc | 7 +
.../testsuite/std/simd/shift_right.cc | 91 +
.../std/simd/shift_right_expensive.cc | 7 +
libstdc++-v3/testsuite/std/simd/simd_alg.cc | 137 +
.../testsuite/std/simd/simd_alg_expensive.cc | 7 +
libstdc++-v3/testsuite/std/simd/sse_intrin.cc | 42 +
libstdc++-v3/testsuite/std/simd/stores.cc | 67 +
.../testsuite/std/simd/stores_expensive.cc | 7 +
libstdc++-v3/testsuite/std/simd/test_setup.h | 809 ++++++
.../testsuite/std/simd/traits_common.cc | 710 +++++
.../testsuite/std/simd/traits_impl.cc | 185 ++
.../testsuite/std/simd/traits_math.cc | 62 +
42 files changed, 11957 insertions(+)
create mode 100644 libstdc++-v3/include/bits/simd_alg.h
create mode 100644 libstdc++-v3/include/bits/simd_details.h
create mode 100644 libstdc++-v3/include/bits/simd_flags.h
create mode 100644 libstdc++-v3/include/bits/simd_iterator.h
create mode 100644 libstdc++-v3/include/bits/simd_loadstore.h
create mode 100644 libstdc++-v3/include/bits/simd_mask.h
create mode 100644 libstdc++-v3/include/bits/simd_mask_reductions.h
create mode 100644 libstdc++-v3/include/bits/simd_reductions.h
create mode 100644 libstdc++-v3/include/bits/simd_vec.h
create mode 100644 libstdc++-v3/include/bits/simd_x86.h
create mode 100644 libstdc++-v3/include/bits/vec_ops.h
create mode 100644 libstdc++-v3/include/std/simd
create mode 100644 libstdc++-v3/testsuite/std/simd/arithmetic.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/arithmetic_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/create_tests.h
create mode 100644 libstdc++-v3/testsuite/std/simd/creation.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/creation_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/loads.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/loads_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/mask.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/mask2.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/mask2_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/mask_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/reductions.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/reductions_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/shift_left.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/shift_left_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/shift_right.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/shift_right_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/simd_alg.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/simd_alg_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/sse_intrin.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/stores.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/stores_expensive.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/test_setup.h
create mode 100644 libstdc++-v3/testsuite/std/simd/traits_common.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/traits_impl.cc
create mode 100644 libstdc++-v3/testsuite/std/simd/traits_math.cc
std::simd
──────────────────────────────────────────────────────────────────────────
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-libstdc-Implement-simd-for-C-26.patch
Type: text/x-patch
Size: 433595 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260321/e8168579/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part.
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260321/e8168579/attachment-0001.sig>
More information about the Libstdc++
mailing list