From 1603fafcf8cd45da71dd6368d48a60abafc60c3b Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 1 Dec 2021 21:45:55 +0200 Subject: [PATCH 1/3] make sure we are rotating in the right direction --- .../test.cpp | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp b/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp index 95eb50bd0c3..07a57e53a58 100644 --- a/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp +++ b/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp @@ -86,9 +86,21 @@ template constexpr bool test_rotl() { constexpr int digits = numeric_limits::digits; constexpr auto maxval = numeric_limits::max(); + + constexpr T every_fourth[4] = { + static_cast(0x1111'1111'1111'1111ULL), + static_cast(0x2222'2222'2222'2222ULL), + static_cast(0x4444'4444'4444'4444ULL), + static_cast(0x8888'8888'8888'8888ULL), + }; + for (int i = 0; i < digits * 2; ++i) { assert(rotl(maxval, i) == maxval); assert(rotl(T{0}, i) == 0); + + for (int j = 0; j < 4; ++j) { + assert(rotl(every_fourth[j], i) == every_fourth[(i + j) % 4]); + } } return true; } @@ -97,9 +109,21 @@ template constexpr bool test_rotr() { constexpr int digits = numeric_limits::digits; constexpr auto maxval = numeric_limits::max(); + + constexpr T every_fourth[4] = { + static_cast(0x1111'1111'1111'1111ULL), + static_cast(0x2222'2222'2222'2222ULL), + static_cast(0x4444'4444'4444'4444ULL), + static_cast(0x8888'8888'8888'8888ULL), + }; + for (int i = 0; i < digits * 2; ++i) { assert(rotr(maxval, i) == maxval); assert(rotr(T{0}, i) == 0); + + for (int j = 0; j < 4; ++j) { + assert(rotr(every_fourth[3 - j], i) == every_fourth[3 - ((i + j) % 4)]); + } } return true; } From bf7b413ddd60da16992ae539b01fc7314d4ce4b9 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 1 Dec 2021 21:46:38 +0200 Subject: [PATCH 2/3] Some intrinsics --- stl/inc/bit | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/stl/inc/bit b/stl/inc/bit index b412a53b968..520b20e1a7a 100644 --- a/stl/inc/bit +++ b/stl/inc/bit @@ -92,7 +92,17 @@ _NODISCARD constexpr _Ty rotr(_Ty _Val, int _Rotation) noexcept; template , int> = 0> _NODISCARD constexpr _Ty rotl(const _Ty _Val, const int _Rotation) noexcept { constexpr auto _Digits = numeric_limits<_Ty>::digits; - const auto _Remainder = _Rotation % _Digits; + + if (!_STD is_constant_evaluated()) { + if constexpr (_Digits == 64) { + return _rotl64(_Val, _Rotation); + } else if constexpr (_Digits == 32) { + return _rotl(_Val, _Rotation); + } + // TRANSITION: fallback to non-intrinsic case until changes + } + + const auto _Remainder = _Rotation % _Digits; if (_Remainder > 0) { return static_cast<_Ty>( static_cast<_Ty>(_Val << _Remainder) | static_cast<_Ty>(_Val >> (_Digits - _Remainder))); @@ -106,7 +116,17 @@ _NODISCARD constexpr _Ty rotl(const _Ty _Val, const int _Rotation) noexcept { template , int> _Enabled> _NODISCARD constexpr _Ty rotr(const _Ty _Val, const int _Rotation) noexcept { constexpr auto _Digits = numeric_limits<_Ty>::digits; - const auto _Remainder = _Rotation % _Digits; + + if (!_STD is_constant_evaluated()) { + if constexpr (_Digits == 64) { + return _rotr64(_Val, _Rotation); + } else if constexpr (_Digits == 32) { + return _rotr(_Val, _Rotation); + } + // TRANSITION: fallback to non-intrinsic case until changes + } + + const auto _Remainder = _Rotation % _Digits; if (_Remainder > 0) { return static_cast<_Ty>( static_cast<_Ty>(_Val >> _Remainder) | static_cast<_Ty>(_Val << (_Digits - _Remainder))); From b05e2e99e8bb3c9af992a482ded5db7c2d0c6529 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Wed, 1 Dec 2021 21:52:04 +0200 Subject: [PATCH 3/3] simplify test --- .../tests/P0553R4_bit_rotating_and_counting_functions/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp b/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp index 07a57e53a58..c73cccfa76b 100644 --- a/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp +++ b/tests/std/tests/P0553R4_bit_rotating_and_counting_functions/test.cpp @@ -122,7 +122,7 @@ constexpr bool test_rotr() { assert(rotr(T{0}, i) == 0); for (int j = 0; j < 4; ++j) { - assert(rotr(every_fourth[3 - j], i) == every_fourth[3 - ((i + j) % 4)]); + assert(rotr(every_fourth[(i + j) % 4], i) == every_fourth[j]); } } return true;