From f1a6aca36694f1faa62a91ece4f53db0a48e9ebc Mon Sep 17 00:00:00 2001 From: danieltowner Date: Tue, 13 Oct 2026 21:26:13 +0100 Subject: [PATCH] Fixed code review issue in rotate/funnel_shift offsets A code review found a corner case in rotates and shifts that led to suspicious behaviour. This issue wasn't present in the implementation described in the standards paper that introduced funnel shifts (P4010). xvec has been modified to match the example implementation of the standards proposal. --- include/xvec/generic/generic_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/xvec/generic/generic_impl.hpp b/include/xvec/generic/generic_impl.hpp index c1465f7..70a2169 100644 --- a/include/xvec/generic/generic_impl.hpp +++ b/include/xvec/generic/generic_impl.hpp @@ -953,7 +953,7 @@ template constexpr basic_vec<_Tp, _Abi> rotate_left(generic_tag, const basic_vec<_Tp, _Abi>& value, const basic_vec<_Sp, _Abi>& s) { constexpr int numBits = sizeof(_Tp) * 8; const auto sm = basic_vec<_Tp, _Abi>(s).to_builtin() % numBits; - const auto r = (value.to_builtin() << sm) | (value.to_builtin() >> (numBits - sm)); + const auto r = (value.to_builtin() << sm) | (value.to_builtin() >> ((numBits - sm) % numBits)); return basic_vec<_Tp, _Abi>(sm != 0 ? r : value.to_builtin()); } @@ -961,7 +961,7 @@ template constexpr basic_vec<_Tp, _Abi> rotate_right(generic_tag, const basic_vec<_Tp, _Abi>& value, const basic_vec<_Sp, _Abi>& s) { constexpr int numBits = sizeof(_Tp) * 8; const auto sm = basic_vec<_Tp, _Abi>(s).to_builtin() % numBits; - const auto r = (value.to_builtin() >> sm) | (value.to_builtin() << (numBits - sm)); + const auto r = (value.to_builtin() >> sm) | (value.to_builtin() << ((numBits - sm) % numBits)); return basic_vec<_Tp, _Abi>(sm != 0 ? r : value.to_builtin()); } ///@} @@ -983,7 +983,7 @@ template constexpr _Vp fsr(generic_tag, const _Vp& high, const _Vp& low, const _Sp& s) { constexpr uint8_t numBits = sizeof(typename _Vp::value_type) * 8; const auto sm = _Vp(s) % numBits; - const _Vp r = (low >> sm) | (high << (numBits - sm)); + const _Vp r = (low >> sm) | (high << ((numBits - sm) % numBits)); return select(sm != _Vp(), r, low); } @@ -992,7 +992,7 @@ template constexpr _Vp fsl(generic_tag, const _Vp& high, const _Vp& low, const _Sp& s) { constexpr uint8_t numBits = sizeof(typename _Vp::value_type) * 8; const auto sm = _Vp(s) % numBits; - const _Vp r = (high << sm) | (low >> (numBits - sm)); + const _Vp r = (high << sm) | (low >> ((numBits - sm) % numBits)); return select(sm != _Vp(), r, high); } ///@}