From: Matthias Kretz Date: Mon, 20 Feb 2023 15:33:31 +0000 (+0100) Subject: libstdc++: More efficient masked inc-/decrement implementation X-Git-Tag: basepoints/gcc-14~874 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ce55180d494b616e2e3e68ffedfe9007e42ca06;p=thirdparty%2Fgcc.git libstdc++: More efficient masked inc-/decrement implementation Signed-off-by: Matthias Kretz libstdc++-v3/ChangeLog: PR libstdc++/108856 * include/experimental/bits/simd_builtin.h (_SimdImplBuiltin::_S_masked_unary): More efficient implementation of masked inc-/decrement for integers and floats without AVX2. * include/experimental/bits/simd_x86.h (_SimdImplX86::_S_masked_unary): New. Use AVX512 masked subtract builtins for masked inc-/decrement. --- diff --git a/libstdc++-v3/include/experimental/bits/simd_builtin.h b/libstdc++-v3/include/experimental/bits/simd_builtin.h index 9736db65e016..0cf5c9897cd1 100644 --- a/libstdc++-v3/include/experimental/bits/simd_builtin.h +++ b/libstdc++-v3/include/experimental/bits/simd_builtin.h @@ -2546,8 +2546,31 @@ template _Op __op; if (__k._M_is_constprop_all_of()) return __data(__op(__vv)); - else - return _CommonImpl::_S_blend(__k, __v, __data(__op(__vv))); + else if constexpr (is_same_v<_Op, __increment>) + { + static_assert(not std::is_same_v<_K, bool>); + if constexpr (is_integral_v<_Tp>) + // Take a shortcut knowing that __k is an integer vector with values -1 or 0. + return __v._M_data - __vector_bitcast<_Tp>(__k._M_data); + else if constexpr (not __have_avx2) + return __v._M_data + + __vector_bitcast<_Tp>(__k._M_data & __builtin_bit_cast( + _K, _Tp(1))); + // starting with AVX2 it is more efficient to blend after add + } + else if constexpr (is_same_v<_Op, __decrement>) + { + static_assert(not std::is_same_v<_K, bool>); + if constexpr (is_integral_v<_Tp>) + // Take a shortcut knowing that __k is an integer vector with values -1 or 0. + return __v._M_data + __vector_bitcast<_Tp>(__k._M_data); + else if constexpr (not __have_avx2) + return __v._M_data + - __vector_bitcast<_Tp>(__k._M_data & __builtin_bit_cast( + _K, _Tp(1))); + // starting with AVX2 it is more efficient to blend after sub + } + return _CommonImpl::_S_blend(__k, __v, __data(__op(__vv))); } //}}}2 diff --git a/libstdc++-v3/include/experimental/bits/simd_x86.h b/libstdc++-v3/include/experimental/bits/simd_x86.h index cd642cb3290f..8872ca301b9e 100644 --- a/libstdc++-v3/include/experimental/bits/simd_x86.h +++ b/libstdc++-v3/include/experimental/bits/simd_x86.h @@ -3462,6 +3462,74 @@ template } //}}} }}} + template