1b703bd82SGuillaume Chatelet //===-- Unittests for Bit -------------------------------------------------===// 2b703bd82SGuillaume Chatelet // 3b703bd82SGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4b703bd82SGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information. 5b703bd82SGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b703bd82SGuillaume Chatelet // 7b703bd82SGuillaume Chatelet //===----------------------------------------------------------------------===// 8b703bd82SGuillaume Chatelet 9b703bd82SGuillaume Chatelet #include "src/__support/CPP/bit.h" 1009efe848SGuillaume Chatelet #include "src/__support/big_int.h" 11*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h" 1223c397c7SGuillaume Chatelet #include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_INT128 13b703bd82SGuillaume Chatelet #include "test/UnitTest/Test.h" 14b703bd82SGuillaume Chatelet 15b703bd82SGuillaume Chatelet #include <stdint.h> 16b703bd82SGuillaume Chatelet 17*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL { 18*5ff3ff33SPetr Hosek namespace cpp { 19b703bd82SGuillaume Chatelet 20245d669fSGuillaume Chatelet using UnsignedTypes = testing::TypeList< 2123c397c7SGuillaume Chatelet #if defined(LIBC_TYPES_HAS_INT128) 22245d669fSGuillaume Chatelet __uint128_t, 2323c397c7SGuillaume Chatelet #endif // LIBC_TYPES_HAS_INT128 24245d669fSGuillaume Chatelet unsigned char, unsigned short, unsigned int, unsigned long, 256a8e6c9aSGuillaume Chatelet unsigned long long, UInt<128>>; 26b703bd82SGuillaume Chatelet 27b703bd82SGuillaume Chatelet TYPED_TEST(LlvmLibcBitTest, HasSingleBit, UnsignedTypes) { 28245d669fSGuillaume Chatelet constexpr auto ZERO = T(0); 29245d669fSGuillaume Chatelet constexpr auto ALL_ONES = T(~ZERO); 30245d669fSGuillaume Chatelet EXPECT_FALSE(has_single_bit<T>(ZERO)); 31245d669fSGuillaume Chatelet EXPECT_FALSE(has_single_bit<T>(ALL_ONES)); 32245d669fSGuillaume Chatelet 33b703bd82SGuillaume Chatelet for (T value = 1; value; value <<= 1) 34b703bd82SGuillaume Chatelet EXPECT_TRUE(has_single_bit<T>(value)); 35245d669fSGuillaume Chatelet 36245d669fSGuillaume Chatelet // We test that if two bits are set has_single_bit returns false. 37245d669fSGuillaume Chatelet // We do this by setting the highest or lowest bit depending or where the 38245d669fSGuillaume Chatelet // current bit is. This is a bit convoluted but it helps catch a bug on BigInt 39245d669fSGuillaume Chatelet // where we have to work on an element-by-element basis. 40245d669fSGuillaume Chatelet constexpr auto MIDPOINT = T(ALL_ONES / 2); 41245d669fSGuillaume Chatelet constexpr auto LSB = T(1); 42245d669fSGuillaume Chatelet constexpr auto MSB = T(~(ALL_ONES >> 1)); 43245d669fSGuillaume Chatelet for (T value = 1; value; value <<= 1) { 44245d669fSGuillaume Chatelet auto two_bits_value = value | ((value <= MIDPOINT) ? MSB : LSB); 45245d669fSGuillaume Chatelet EXPECT_FALSE(has_single_bit<T>(two_bits_value)); 46245d669fSGuillaume Chatelet } 47b703bd82SGuillaume Chatelet } 48b703bd82SGuillaume Chatelet 49b703bd82SGuillaume Chatelet TYPED_TEST(LlvmLibcBitTest, CountLZero, UnsignedTypes) { 50b703bd82SGuillaume Chatelet EXPECT_EQ(countl_zero<T>(T(0)), cpp::numeric_limits<T>::digits); 51b703bd82SGuillaume Chatelet int expected = 0; 52b703bd82SGuillaume Chatelet for (T value = ~T(0); value; value >>= 1, ++expected) 53b703bd82SGuillaume Chatelet EXPECT_EQ(countl_zero<T>(value), expected); 54b703bd82SGuillaume Chatelet } 55b703bd82SGuillaume Chatelet 56b703bd82SGuillaume Chatelet TYPED_TEST(LlvmLibcBitTest, CountRZero, UnsignedTypes) { 57b703bd82SGuillaume Chatelet EXPECT_EQ(countr_zero<T>(T(0)), cpp::numeric_limits<T>::digits); 58b703bd82SGuillaume Chatelet int expected = 0; 59b703bd82SGuillaume Chatelet for (T value = ~T(0); value; value <<= 1, ++expected) 60b703bd82SGuillaume Chatelet EXPECT_EQ(countr_zero<T>(value), expected); 61b703bd82SGuillaume Chatelet } 62b703bd82SGuillaume Chatelet 63b703bd82SGuillaume Chatelet TYPED_TEST(LlvmLibcBitTest, CountLOne, UnsignedTypes) { 64b703bd82SGuillaume Chatelet EXPECT_EQ(countl_one<T>(T(0)), 0); 65b703bd82SGuillaume Chatelet int expected = cpp::numeric_limits<T>::digits; 66b703bd82SGuillaume Chatelet for (T value = ~T(0); value; value <<= 1, --expected) 67b703bd82SGuillaume Chatelet EXPECT_EQ(countl_one<T>(value), expected); 68b703bd82SGuillaume Chatelet } 69b703bd82SGuillaume Chatelet 70b703bd82SGuillaume Chatelet TYPED_TEST(LlvmLibcBitTest, CountROne, UnsignedTypes) { 71b703bd82SGuillaume Chatelet EXPECT_EQ(countr_one<T>(T(0)), 0); 72b703bd82SGuillaume Chatelet int expected = cpp::numeric_limits<T>::digits; 73b703bd82SGuillaume Chatelet for (T value = ~T(0); value; value >>= 1, --expected) 74b703bd82SGuillaume Chatelet EXPECT_EQ(countr_one<T>(value), expected); 75b703bd82SGuillaume Chatelet } 76b703bd82SGuillaume Chatelet 77b703bd82SGuillaume Chatelet TYPED_TEST(LlvmLibcBitTest, BitWidth, UnsignedTypes) { 78b703bd82SGuillaume Chatelet EXPECT_EQ(bit_width<T>(T(0)), 0); 79b703bd82SGuillaume Chatelet int one_index = 0; 80b703bd82SGuillaume Chatelet for (T value = 1; value; value <<= 1, ++one_index) 81b703bd82SGuillaume Chatelet EXPECT_EQ(bit_width<T>(value), one_index + 1); 82b703bd82SGuillaume Chatelet } 83b703bd82SGuillaume Chatelet 84b703bd82SGuillaume Chatelet TEST(LlvmLibcBitTest, BitCeil) { 85b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(1), bit_ceil(uint8_t(0))); 86b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(1), bit_ceil(uint16_t(0))); 87b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(1), bit_ceil(uint32_t(0))); 88b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(1), bit_ceil(uint64_t(0))); 89b703bd82SGuillaume Chatelet 90b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(1), bit_ceil(uint8_t(1))); 91b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(1), bit_ceil(uint16_t(1))); 92b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(1), bit_ceil(uint32_t(1))); 93b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(1), bit_ceil(uint64_t(1))); 94b703bd82SGuillaume Chatelet 95b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(2), bit_ceil(uint8_t(2))); 96b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(2), bit_ceil(uint16_t(2))); 97b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(2), bit_ceil(uint32_t(2))); 98b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(2), bit_ceil(uint64_t(2))); 99b703bd82SGuillaume Chatelet 100b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(4), bit_ceil(uint8_t(3))); 101b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(4), bit_ceil(uint16_t(3))); 102b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(4), bit_ceil(uint32_t(3))); 103b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(4), bit_ceil(uint64_t(3))); 104b703bd82SGuillaume Chatelet 105b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(4), bit_ceil(uint8_t(4))); 106b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(4), bit_ceil(uint16_t(4))); 107b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(4), bit_ceil(uint32_t(4))); 108b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(4), bit_ceil(uint64_t(4))); 109b703bd82SGuillaume Chatelet 110b703bd82SGuillaume Chatelet // The result is the representable power of 2 for each type. 111b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x80), bit_ceil(uint8_t(0x7f))); 112b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0x8000), bit_ceil(uint16_t(0x7fff))); 113b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0x80000000), bit_ceil(uint32_t(0x7fffffff))); 114b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x8000000000000000), 115b703bd82SGuillaume Chatelet bit_ceil(uint64_t(0x7fffffffffffffff))); 116b703bd82SGuillaume Chatelet } 117b703bd82SGuillaume Chatelet 118b703bd82SGuillaume Chatelet TEST(LlvmLibcBitTest, BitFloor) { 119b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0), bit_floor(uint8_t(0))); 120b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0), bit_floor(uint16_t(0))); 121b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0), bit_floor(uint32_t(0))); 122b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0), bit_floor(uint64_t(0))); 123b703bd82SGuillaume Chatelet 124b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(1), bit_floor(uint8_t(1))); 125b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(1), bit_floor(uint16_t(1))); 126b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(1), bit_floor(uint32_t(1))); 127b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(1), bit_floor(uint64_t(1))); 128b703bd82SGuillaume Chatelet 129b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(2), bit_floor(uint8_t(2))); 130b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(2), bit_floor(uint16_t(2))); 131b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(2), bit_floor(uint32_t(2))); 132b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(2), bit_floor(uint64_t(2))); 133b703bd82SGuillaume Chatelet 134b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(2), bit_floor(uint8_t(3))); 135b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(2), bit_floor(uint16_t(3))); 136b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(2), bit_floor(uint32_t(3))); 137b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(2), bit_floor(uint64_t(3))); 138b703bd82SGuillaume Chatelet 139b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(4), bit_floor(uint8_t(4))); 140b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(4), bit_floor(uint16_t(4))); 141b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(4), bit_floor(uint32_t(4))); 142b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(4), bit_floor(uint64_t(4))); 143b703bd82SGuillaume Chatelet 144b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x40), bit_floor(uint8_t(0x7f))); 145b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0x4000), bit_floor(uint16_t(0x7fff))); 146b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0x40000000), bit_floor(uint32_t(0x7fffffff))); 147b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x4000000000000000), 148b703bd82SGuillaume Chatelet bit_floor(uint64_t(0x7fffffffffffffffull))); 149b703bd82SGuillaume Chatelet 150b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x80), bit_floor(uint8_t(0x80))); 151b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0x8000), bit_floor(uint16_t(0x8000))); 152b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0x80000000), bit_floor(uint32_t(0x80000000))); 153b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x8000000000000000), 154b703bd82SGuillaume Chatelet bit_floor(uint64_t(0x8000000000000000))); 155b703bd82SGuillaume Chatelet 156b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x80), bit_floor(uint8_t(0xff))); 157b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0x8000), bit_floor(uint16_t(0xffff))); 158b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0x80000000), bit_floor(uint32_t(0xffffffff))); 159b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x8000000000000000), 160b703bd82SGuillaume Chatelet bit_floor(uint64_t(0xffffffffffffffff))); 161b703bd82SGuillaume Chatelet } 162b703bd82SGuillaume Chatelet 163b703bd82SGuillaume Chatelet TYPED_TEST(LlvmLibcBitTest, RotateIsInvariantForZeroAndOne, UnsignedTypes) { 164b703bd82SGuillaume Chatelet constexpr T all_zeros = T(0); 165b703bd82SGuillaume Chatelet constexpr T all_ones = ~T(0); 166b703bd82SGuillaume Chatelet for (int i = 0; i < cpp::numeric_limits<T>::digits; ++i) { 167b703bd82SGuillaume Chatelet EXPECT_EQ(rotl<T>(all_zeros, i), all_zeros); 168b703bd82SGuillaume Chatelet EXPECT_EQ(rotl<T>(all_ones, i), all_ones); 169b703bd82SGuillaume Chatelet EXPECT_EQ(rotr<T>(all_zeros, i), all_zeros); 170b703bd82SGuillaume Chatelet EXPECT_EQ(rotr<T>(all_ones, i), all_ones); 171b703bd82SGuillaume Chatelet } 172b703bd82SGuillaume Chatelet } 173b703bd82SGuillaume Chatelet 174b703bd82SGuillaume Chatelet TEST(LlvmLibcBitTest, Rotl) { 175b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x53U), rotl<uint8_t>(0x53, 0)); 176b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x4dU), rotl<uint8_t>(0x53, 2)); 177b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0xa6U), rotl<uint8_t>(0x53, 9)); 178b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x9aU), rotl<uint8_t>(0x53, -5)); 179b703bd82SGuillaume Chatelet 180b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0xabcdU), rotl<uint16_t>(0xabcd, 0)); 181b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0xf36aU), rotl<uint16_t>(0xabcd, 6)); 182b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0xaf36U), rotl<uint16_t>(0xabcd, 18)); 183b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0xf36aU), rotl<uint16_t>(0xabcd, -10)); 184b703bd82SGuillaume Chatelet 185b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0xdeadbeefU), rotl<uint32_t>(0xdeadbeef, 0)); 186b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0x7ddfbd5bU), rotl<uint32_t>(0xdeadbeef, 17)); 187b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0x5b7ddfbdU), rotl<uint32_t>(0xdeadbeef, 41)); 188b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0xb6fbbf7aU), rotl<uint32_t>(0xdeadbeef, -22)); 189b703bd82SGuillaume Chatelet 190b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x12345678deadbeefULL), 191b703bd82SGuillaume Chatelet rotl<uint64_t>(0x12345678deadbeefULL, 0)); 192b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0xf56df77891a2b3c6ULL), 193b703bd82SGuillaume Chatelet rotl<uint64_t>(0x12345678deadbeefULL, 35)); 194b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x8d159e37ab6fbbc4ULL), 195b703bd82SGuillaume Chatelet rotl<uint64_t>(0x12345678deadbeefULL, 70)); 196b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0xb7dde2468acf1bd5ULL), 197b703bd82SGuillaume Chatelet rotl<uint64_t>(0x12345678deadbeefULL, -19)); 198b703bd82SGuillaume Chatelet } 199b703bd82SGuillaume Chatelet 200b703bd82SGuillaume Chatelet TEST(LlvmLibcBitTest, Rotr) { 201b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x53U), rotr<uint8_t>(0x53, 0)); 202b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0xd4U), rotr<uint8_t>(0x53, 2)); 203b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0xa9U), rotr<uint8_t>(0x53, 9)); 204b703bd82SGuillaume Chatelet EXPECT_EQ(uint8_t(0x6aU), rotr<uint8_t>(0x53, -5)); 205b703bd82SGuillaume Chatelet 206b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0xabcdU), rotr<uint16_t>(0xabcd, 0)); 207b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0x36afU), rotr<uint16_t>(0xabcd, 6)); 208b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0x6af3U), rotr<uint16_t>(0xabcd, 18)); 209b703bd82SGuillaume Chatelet EXPECT_EQ(uint16_t(0x36afU), rotr<uint16_t>(0xabcd, -10)); 210b703bd82SGuillaume Chatelet 211b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0xdeadbeefU), rotr<uint32_t>(0xdeadbeef, 0)); 212b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0xdf77ef56U), rotr<uint32_t>(0xdeadbeef, 17)); 213b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0x77ef56dfU), rotr<uint32_t>(0xdeadbeef, 41)); 214b703bd82SGuillaume Chatelet EXPECT_EQ(uint32_t(0xbbf7ab6fU), rotr<uint32_t>(0xdeadbeef, -22)); 215b703bd82SGuillaume Chatelet 216b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x12345678deadbeefULL), 217b703bd82SGuillaume Chatelet rotr<uint64_t>(0x12345678deadbeefULL, 0)); 218b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0x1bd5b7dde2468acfULL), 219b703bd82SGuillaume Chatelet rotr<uint64_t>(0x12345678deadbeefULL, 35)); 220b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0xbc48d159e37ab6fbULL), 221b703bd82SGuillaume Chatelet rotr<uint64_t>(0x12345678deadbeefULL, 70)); 222b703bd82SGuillaume Chatelet EXPECT_EQ(uint64_t(0xb3c6f56df77891a2ULL), 223b703bd82SGuillaume Chatelet rotr<uint64_t>(0x12345678deadbeefULL, -19)); 224b703bd82SGuillaume Chatelet } 225b703bd82SGuillaume Chatelet 22651f7b262SNick Desaulniers TYPED_TEST(LlvmLibcBitTest, CountOnes, UnsignedTypes) { 227293ec486SNick Desaulniers EXPECT_EQ(popcount(T(0)), 0); 228ed4bdb86SNick Desaulniers for (int i = 0; i != cpp::numeric_limits<T>::digits; ++i) 229293ec486SNick Desaulniers EXPECT_EQ(popcount<T>(cpp::numeric_limits<T>::max() >> i), 230ed4bdb86SNick Desaulniers cpp::numeric_limits<T>::digits - i); 231ed4bdb86SNick Desaulniers } 232ed4bdb86SNick Desaulniers 233*5ff3ff33SPetr Hosek } // namespace cpp 234*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL 235