xref: /llvm-project/libc/test/src/__support/CPP/bit_test.cpp (revision 5ff3ff33ff930e4ec49da7910612d8a41eb068cb)
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