I think this is something worth discussing on the usual list channel, so
people not looking
at forge will also get notice, so posting in here:
In the patch, there is a lot of code that looks like this:
if (__builtin_is_constant_evaluated() || (__builtin_constant_p(__arg0) &&
__builtin_constant_p(__arg1))
{
// some compile-time compatible coded
}
else
{
// optimized version
}
The __builtin_is_constant_evaluated part is uncontroversial, as we are
guaranteed that the code
will get folded at compile time, and never be evaluated at runtime.
However, we assume that if the
arg0 and arg1 are building constant, the compiler will constant fold the
code. But it is not required to
do so. I believe that you have verified that this is the case on most
common optimization level, but
I think this may lead to surprises for users, for example on debug builds.
This also does not scale well for-used defined types. However, I also do
not want to simply as you
to drop this functionality, so what I suggest instead is to introduce:
template<typename... _Args>
[[__gnu__::__always_inline__]]
constexpr __should_constprop(const _Args&... __args)
{
if conteval { // of if (__builtin_is_constant_evaluated())
return true;
}
return __is_constprop(__args) && ...;
}
The _M_isconstprop member on simd, should become __is_constprop hidden
friend.
Where is_constprop is defined as:
template<typename _Tp>
[[__gnu__::__always_inline__]]
constexpr bool
__is_constprop(const _Tp& _tp)
{
if constexpr (__complex_like<_Tp>)
return __is_constprop(__x.real()) and __is_constprop(__x.imag());
else
return __builtin_constant_p(__x);
}
And basic_simd::_M_isconstprop become hidden __is_constrop friend, so they
will be better
candidates.
Similarly __constant_propagate_eq(). You already have something similar as
__constprop
workaround:
// work around __builtin_constant_p returning false unless passed a
variable
// (__builtin_constant_p(x[0]) is false while __is_constprop(x[0]) is
true)
[[__gnu__::__always_inline__]]
constexpr bool
__is_constprop(const auto& __x)
{ return __builtin_is_constant_evaluated() or __builtin_constant_p(__x); }
This would allow us to control the constant propagation from arguments in
one place, and disable
it if it's found problematic.
Regards,
Tomasz
On Wed, Oct 8, 2025 at 1:54 PM Matthias Kretz <[email protected]> wrote:
> This set of patches implements C++26 [simd]. The implementation differs a
> lot
> from the std::experimental implementation. I tried my best to reduce the
> number of template instantiations wrt. what std::experimental::simd does.
>
> A basic_vec/basic_mask that uses multiple registers is built as a tree of
> smaller specializations, where the left branch always stores a power-of-2
> number of elements.
>
> Still missing: [simd.loadstore], [simd.permute.dynamic],
> [simd.permute.mask],
> [simd.permute.memory].
>
> [simd.math] is partially implemented. But I don't want to go any further
> on
> this without some feedback on the direction I took.
>
> I have an extensive set of unit tests at
> https://github.com/GSI-HPC/simd/tree/
> rewrite. But I don't want to repeat what I did for
> std::experimental::simd. So
> I'll look into possibly keeping an external complete simd testsuite while
> added some tests to libstdc++ later.
>
> The PR is split into multiple commits to hopefully make it easier to get
> through the review.
>
> Matthias Kretz (11):
> libstdc++: C++26 [simd] details
> libstdc++: Implement C++26 [simd.iterator]
> libstdc++: C++26 [simd] rebind, resize, permute, chunk, cat and
> basic_mask
> libstdc++: Implement C++26 [simd.mask.reductions]
> libstdc++: Implement C++26 [simd.flags] and alignment(_v)
> libstdc++: Implement C++26 [simd] basic_vec
> libstdc++: Implement C++26 [simd.alg]
> libstdc++: Implement C++26 [simd.bit]
> libstdc++: Implement C++26 [simd.reductions]
> libstdc++: Specialize basic_mask and basic_vec for complex value-types
> libstdc++: First sketch for C++26 [simd.math]
>
> libstdc++-v3/include/bits/simd_alg.h | 76 +
> libstdc++-v3/include/bits/simd_bit.h | 156 ++
> libstdc++-v3/include/bits/simd_complex.h | 1342 +++++++++++
> libstdc++-v3/include/bits/simd_details.h | 1443 +++++++++++
> libstdc++-v3/include/bits/simd_flags.h | 265 ++
> libstdc++-v3/include/bits/simd_iterator.h | 153 ++
> libstdc++-v3/include/bits/simd_mask.h | 1732 ++++++++++++++
> .../include/bits/simd_mask_reductions.h | 94 +
> libstdc++-v3/include/bits/simd_math.h | 993 ++++++++
> libstdc++-v3/include/bits/simd_reductions.h | 112 +
> libstdc++-v3/include/bits/simd_vec.h | 2130 +++++++++++++++++
> libstdc++-v3/include/bits/simd_x86.h | 953 ++++++++
> libstdc++-v3/include/bits/vec_ops.h | 592 +++++
> 13 files changed, 10041 insertions(+)
> create mode 100644 libstdc++-v3/include/bits/simd_alg.h
> create mode 100644 libstdc++-v3/include/bits/simd_bit.h
> create mode 100644 libstdc++-v3/include/bits/simd_complex.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_mask.h
> create mode 100644 libstdc++-v3/include/bits/simd_mask_reductions.h
> create mode 100644 libstdc++-v3/include/bits/simd_math.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
>
> --
> ──────────────────────────────────────────────────────────────────────────
> Dr. Matthias Kretz https://mattkretz.github.io
> GSI Helmholtz Center for Heavy Ion Research https://gsi.de
> std::simd
> ──────────────────────────────────────────────────────────────────────────
>
>
>
>
>