From 6ce55180d494b616e2e3e68ffedfe9007e42ca06 Mon Sep 17 00:00:00 2001 From: Matthias Kretz Date: Mon, 20 Feb 2023 16:33:31 +0100 Subject: [PATCH] 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. --- .../include/experimental/bits/simd_builtin.h | 27 +++++++- .../include/experimental/bits/simd_x86.h | 68 +++++++++++++++++++ 2 files changed, 93 insertions(+), 2 deletions(-) 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