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

source code of libc/test/src/__support/CPP/bit_test.cpp