1*9880d681SAndroid Build Coastguard Worker //===- unittests/Support/MathExtrasTest.cpp - math utils tests ------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker using namespace llvm;
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker namespace {
16*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,countTrailingZeros)17*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, countTrailingZeros) {
18*9880d681SAndroid Build Coastguard Worker uint8_t Z8 = 0;
19*9880d681SAndroid Build Coastguard Worker uint16_t Z16 = 0;
20*9880d681SAndroid Build Coastguard Worker uint32_t Z32 = 0;
21*9880d681SAndroid Build Coastguard Worker uint64_t Z64 = 0;
22*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(8u, countTrailingZeros(Z8));
23*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(16u, countTrailingZeros(Z16));
24*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(32u, countTrailingZeros(Z32));
25*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(64u, countTrailingZeros(Z64));
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker uint8_t NZ8 = 42;
28*9880d681SAndroid Build Coastguard Worker uint16_t NZ16 = 42;
29*9880d681SAndroid Build Coastguard Worker uint32_t NZ32 = 42;
30*9880d681SAndroid Build Coastguard Worker uint64_t NZ64 = 42;
31*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, countTrailingZeros(NZ8));
32*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, countTrailingZeros(NZ16));
33*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, countTrailingZeros(NZ32));
34*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, countTrailingZeros(NZ64));
35*9880d681SAndroid Build Coastguard Worker }
36*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,countLeadingZeros)37*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, countLeadingZeros) {
38*9880d681SAndroid Build Coastguard Worker uint8_t Z8 = 0;
39*9880d681SAndroid Build Coastguard Worker uint16_t Z16 = 0;
40*9880d681SAndroid Build Coastguard Worker uint32_t Z32 = 0;
41*9880d681SAndroid Build Coastguard Worker uint64_t Z64 = 0;
42*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(8u, countLeadingZeros(Z8));
43*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(16u, countLeadingZeros(Z16));
44*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(32u, countLeadingZeros(Z32));
45*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(64u, countLeadingZeros(Z64));
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker uint8_t NZ8 = 42;
48*9880d681SAndroid Build Coastguard Worker uint16_t NZ16 = 42;
49*9880d681SAndroid Build Coastguard Worker uint32_t NZ32 = 42;
50*9880d681SAndroid Build Coastguard Worker uint64_t NZ64 = 42;
51*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(2u, countLeadingZeros(NZ8));
52*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(10u, countLeadingZeros(NZ16));
53*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(26u, countLeadingZeros(NZ32));
54*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(58u, countLeadingZeros(NZ64));
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(8u, countLeadingZeros(0x00F000FFu));
57*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(8u, countLeadingZeros(0x00F12345u));
58*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i <= 30; ++i) {
59*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(31 - i, countLeadingZeros(1u << i));
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(8u, countLeadingZeros(0x00F1234500F12345ULL));
63*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, countLeadingZeros(1ULL << 62));
64*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i <= 62; ++i) {
65*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(63 - i, countLeadingZeros(1ULL << i));
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,findFirstSet)69*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, findFirstSet) {
70*9880d681SAndroid Build Coastguard Worker uint8_t Z8 = 0;
71*9880d681SAndroid Build Coastguard Worker uint16_t Z16 = 0;
72*9880d681SAndroid Build Coastguard Worker uint32_t Z32 = 0;
73*9880d681SAndroid Build Coastguard Worker uint64_t Z64 = 0;
74*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFULL, findFirstSet(Z8));
75*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFFFULL, findFirstSet(Z16));
76*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFFFFFFFULL, findFirstSet(Z32));
77*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, findFirstSet(Z64));
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker uint8_t NZ8 = 42;
80*9880d681SAndroid Build Coastguard Worker uint16_t NZ16 = 42;
81*9880d681SAndroid Build Coastguard Worker uint32_t NZ32 = 42;
82*9880d681SAndroid Build Coastguard Worker uint64_t NZ64 = 42;
83*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, findFirstSet(NZ8));
84*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, findFirstSet(NZ16));
85*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, findFirstSet(NZ32));
86*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, findFirstSet(NZ64));
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,findLastSet)89*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, findLastSet) {
90*9880d681SAndroid Build Coastguard Worker uint8_t Z8 = 0;
91*9880d681SAndroid Build Coastguard Worker uint16_t Z16 = 0;
92*9880d681SAndroid Build Coastguard Worker uint32_t Z32 = 0;
93*9880d681SAndroid Build Coastguard Worker uint64_t Z64 = 0;
94*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFULL, findLastSet(Z8));
95*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFFFULL, findLastSet(Z16));
96*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFFFFFFFULL, findLastSet(Z32));
97*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, findLastSet(Z64));
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker uint8_t NZ8 = 42;
100*9880d681SAndroid Build Coastguard Worker uint16_t NZ16 = 42;
101*9880d681SAndroid Build Coastguard Worker uint32_t NZ32 = 42;
102*9880d681SAndroid Build Coastguard Worker uint64_t NZ64 = 42;
103*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(5u, findLastSet(NZ8));
104*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(5u, findLastSet(NZ16));
105*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(5u, findLastSet(NZ32));
106*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(5u, findLastSet(NZ64));
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,isIntN)109*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, isIntN) {
110*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isIntN(16, 32767));
111*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(isIntN(16, 32768));
112*9880d681SAndroid Build Coastguard Worker }
113*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,isUIntN)114*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, isUIntN) {
115*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isUIntN(16, 65535));
116*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(isUIntN(16, 65536));
117*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isUIntN(1, 0));
118*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isUIntN(6, 63));
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,maxIntN)121*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, maxIntN) {
122*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(32767, maxIntN(16));
123*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(2147483647, maxIntN(32));
124*9880d681SAndroid Build Coastguard Worker }
125*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,minIntN)126*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, minIntN) {
127*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(-32768LL, minIntN(16));
128*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(-64LL, minIntN(7));
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,maxUIntN)131*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, maxUIntN) {
132*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xffffULL, maxUIntN(16));
133*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xffffffffULL, maxUIntN(32));
134*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1ULL, maxUIntN(1));
135*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x0fULL, maxUIntN(4));
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,reverseBits)138*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, reverseBits) {
139*9880d681SAndroid Build Coastguard Worker uint8_t NZ8 = 42;
140*9880d681SAndroid Build Coastguard Worker uint16_t NZ16 = 42;
141*9880d681SAndroid Build Coastguard Worker uint32_t NZ32 = 42;
142*9880d681SAndroid Build Coastguard Worker uint64_t NZ64 = 42;
143*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x54ULL, reverseBits(NZ8));
144*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x5400ULL, reverseBits(NZ16));
145*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x54000000ULL, reverseBits(NZ32));
146*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x5400000000000000ULL, reverseBits(NZ64));
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,isPowerOf2_32)149*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, isPowerOf2_32) {
150*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isPowerOf2_32(1 << 6));
151*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isPowerOf2_32(1 << 12));
152*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(isPowerOf2_32((1 << 19) + 3));
153*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(isPowerOf2_32(0xABCDEF0));
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,isPowerOf2_64)156*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, isPowerOf2_64) {
157*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isPowerOf2_64(1LL << 46));
158*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(isPowerOf2_64(1LL << 12));
159*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(isPowerOf2_64((1LL << 53) + 3));
160*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(isPowerOf2_64(0xABCDEF0ABCDEF0LL));
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,ByteSwap_32)163*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, ByteSwap_32) {
164*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x44332211u, ByteSwap_32(0x11223344));
165*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0xDDCCBBAAu, ByteSwap_32(0xAABBCCDD));
166*9880d681SAndroid Build Coastguard Worker }
167*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,ByteSwap_64)168*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, ByteSwap_64) {
169*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x8877665544332211ULL, ByteSwap_64(0x1122334455667788LL));
170*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0x1100FFEEDDCCBBAAULL, ByteSwap_64(0xAABBCCDDEEFF0011LL));
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,countLeadingOnes)173*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, countLeadingOnes) {
174*9880d681SAndroid Build Coastguard Worker for (int i = 30; i >= 0; --i) {
175*9880d681SAndroid Build Coastguard Worker // Start with all ones and unset some bit.
176*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(31u - i, countLeadingOnes(0xFFFFFFFF ^ (1 << i)));
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker for (int i = 62; i >= 0; --i) {
179*9880d681SAndroid Build Coastguard Worker // Start with all ones and unset some bit.
180*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(63u - i, countLeadingOnes(0xFFFFFFFFFFFFFFFFULL ^ (1LL << i)));
181*9880d681SAndroid Build Coastguard Worker }
182*9880d681SAndroid Build Coastguard Worker for (int i = 30; i >= 0; --i) {
183*9880d681SAndroid Build Coastguard Worker // Start with all ones and unset some bit.
184*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(31u - i, countLeadingOnes(0xFFFFFFFF ^ (1 << i)));
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker }
187*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,FloatBits)188*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, FloatBits) {
189*9880d681SAndroid Build Coastguard Worker static const float kValue = 5632.34f;
190*9880d681SAndroid Build Coastguard Worker EXPECT_FLOAT_EQ(kValue, BitsToFloat(FloatToBits(kValue)));
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,DoubleBits)193*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, DoubleBits) {
194*9880d681SAndroid Build Coastguard Worker static const double kValue = 87987234.983498;
195*9880d681SAndroid Build Coastguard Worker EXPECT_DOUBLE_EQ(kValue, BitsToDouble(DoubleToBits(kValue)));
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,MinAlign)198*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, MinAlign) {
199*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, MinAlign(2, 3));
200*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(2u, MinAlign(2, 4));
201*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1u, MinAlign(17, 64));
202*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(256u, MinAlign(256, 512));
203*9880d681SAndroid Build Coastguard Worker }
204*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,NextPowerOf2)205*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, NextPowerOf2) {
206*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(4u, NextPowerOf2(3));
207*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(16u, NextPowerOf2(15));
208*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(256u, NextPowerOf2(128));
209*9880d681SAndroid Build Coastguard Worker }
210*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,alignTo)211*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, alignTo) {
212*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(8u, alignTo(5, 8));
213*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(24u, alignTo(17, 8));
214*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0u, alignTo(~0LL, 8));
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(7u, alignTo(5, 8, 7));
217*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(17u, alignTo(17, 8, 1));
218*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(3u, alignTo(~0LL, 8, 3));
219*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(552u, alignTo(321, 255, 42));
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker template<typename T>
SaturatingAddTestHelper()223*9880d681SAndroid Build Coastguard Worker void SaturatingAddTestHelper()
224*9880d681SAndroid Build Coastguard Worker {
225*9880d681SAndroid Build Coastguard Worker const T Max = std::numeric_limits<T>::max();
226*9880d681SAndroid Build Coastguard Worker bool ResultOverflowed;
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2)));
229*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2), &ResultOverflowed));
230*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(Max, T(1)));
233*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(Max, T(1), &ResultOverflowed));
234*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 1)));
237*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 1), &ResultOverflowed));
238*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(T(1), Max));
241*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(T(1), Max, &ResultOverflowed));
242*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(Max, Max));
245*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingAdd(Max, Max, &ResultOverflowed));
246*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
247*9880d681SAndroid Build Coastguard Worker }
248*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,SaturatingAdd)249*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, SaturatingAdd) {
250*9880d681SAndroid Build Coastguard Worker SaturatingAddTestHelper<uint8_t>();
251*9880d681SAndroid Build Coastguard Worker SaturatingAddTestHelper<uint16_t>();
252*9880d681SAndroid Build Coastguard Worker SaturatingAddTestHelper<uint32_t>();
253*9880d681SAndroid Build Coastguard Worker SaturatingAddTestHelper<uint64_t>();
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker template<typename T>
SaturatingMultiplyTestHelper()257*9880d681SAndroid Build Coastguard Worker void SaturatingMultiplyTestHelper()
258*9880d681SAndroid Build Coastguard Worker {
259*9880d681SAndroid Build Coastguard Worker const T Max = std::numeric_limits<T>::max();
260*9880d681SAndroid Build Coastguard Worker bool ResultOverflowed;
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker // Test basic multiplication.
263*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3)));
264*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3), &ResultOverflowed));
265*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(6), SaturatingMultiply(T(3), T(2)));
268*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(6), SaturatingMultiply(T(3), T(2), &ResultOverflowed));
269*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker // Test multiplication by zero.
272*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(0)));
273*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(0), &ResultOverflowed));
274*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(1), T(0)));
277*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(1), T(0), &ResultOverflowed));
278*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
279*9880d681SAndroid Build Coastguard Worker
280*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(1)));
281*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(1), &ResultOverflowed));
282*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(Max, T(0)));
285*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(Max, T(0), &ResultOverflowed));
286*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
287*9880d681SAndroid Build Coastguard Worker
288*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(0), Max));
289*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiply(T(0), Max, &ResultOverflowed));
290*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
291*9880d681SAndroid Build Coastguard Worker
292*9880d681SAndroid Build Coastguard Worker // Test multiplication by maximum value.
293*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(Max, T(2)));
294*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(Max, T(2), &ResultOverflowed));
295*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(T(2), Max));
298*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(T(2), Max, &ResultOverflowed));
299*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(Max, Max));
302*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(Max, Max, &ResultOverflowed));
303*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker // Test interesting boundary conditions for algorithm -
306*9880d681SAndroid Build Coastguard Worker // ((1 << A) - 1) * ((1 << B) + K) for K in [-1, 0, 1]
307*9880d681SAndroid Build Coastguard Worker // and A + B == std::numeric_limits<T>::digits.
308*9880d681SAndroid Build Coastguard Worker // We expect overflow iff A > B and K = 1.
309*9880d681SAndroid Build Coastguard Worker const int Digits = std::numeric_limits<T>::digits;
310*9880d681SAndroid Build Coastguard Worker for (int A = 1, B = Digits - 1; B >= 1; ++A, --B) {
311*9880d681SAndroid Build Coastguard Worker for (int K = -1; K <= 1; ++K) {
312*9880d681SAndroid Build Coastguard Worker T X = (T(1) << A) - T(1);
313*9880d681SAndroid Build Coastguard Worker T Y = (T(1) << B) + K;
314*9880d681SAndroid Build Coastguard Worker bool OverflowExpected = A > B && K == 1;
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker if(OverflowExpected) {
317*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(X, Y));
318*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiply(X, Y, &ResultOverflowed));
319*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
320*9880d681SAndroid Build Coastguard Worker } else {
321*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(X * Y, SaturatingMultiply(X, Y));
322*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(X * Y, SaturatingMultiply(X, Y, &ResultOverflowed));
323*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
324*9880d681SAndroid Build Coastguard Worker }
325*9880d681SAndroid Build Coastguard Worker }
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,SaturatingMultiply)329*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, SaturatingMultiply) {
330*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyTestHelper<uint8_t>();
331*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyTestHelper<uint16_t>();
332*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyTestHelper<uint32_t>();
333*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyTestHelper<uint64_t>();
334*9880d681SAndroid Build Coastguard Worker }
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker template<typename T>
SaturatingMultiplyAddTestHelper()337*9880d681SAndroid Build Coastguard Worker void SaturatingMultiplyAddTestHelper()
338*9880d681SAndroid Build Coastguard Worker {
339*9880d681SAndroid Build Coastguard Worker const T Max = std::numeric_limits<T>::max();
340*9880d681SAndroid Build Coastguard Worker bool ResultOverflowed;
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker // Test basic multiply-add.
343*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(16), SaturatingMultiplyAdd(T(2), T(3), T(10)));
344*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(16), SaturatingMultiplyAdd(T(2), T(3), T(10), &ResultOverflowed));
345*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Worker // Test multiply overflows, add doesn't overflow
348*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiplyAdd(Max, Max, T(0), &ResultOverflowed));
349*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Worker // Test multiply doesn't overflow, add overflows
352*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiplyAdd(T(1), T(1), Max, &ResultOverflowed));
353*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker // Test multiply-add with Max as operand
356*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiplyAdd(T(1), T(1), Max, &ResultOverflowed));
357*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiplyAdd(T(1), Max, T(1), &ResultOverflowed));
360*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiplyAdd(Max, Max, T(1), &ResultOverflowed));
363*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
364*9880d681SAndroid Build Coastguard Worker
365*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(Max, SaturatingMultiplyAdd(Max, Max, Max, &ResultOverflowed));
366*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(ResultOverflowed);
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Worker // Test multiply-add with 0 as operand
369*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(1), SaturatingMultiplyAdd(T(1), T(1), T(0), &ResultOverflowed));
370*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(1), SaturatingMultiplyAdd(T(1), T(0), T(1), &ResultOverflowed));
373*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(1), SaturatingMultiplyAdd(T(0), T(0), T(1), &ResultOverflowed));
376*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
377*9880d681SAndroid Build Coastguard Worker
378*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(T(0), SaturatingMultiplyAdd(T(0), T(0), T(0), &ResultOverflowed));
379*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(ResultOverflowed);
380*9880d681SAndroid Build Coastguard Worker
381*9880d681SAndroid Build Coastguard Worker }
382*9880d681SAndroid Build Coastguard Worker
TEST(MathExtras,SaturatingMultiplyAdd)383*9880d681SAndroid Build Coastguard Worker TEST(MathExtras, SaturatingMultiplyAdd) {
384*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyAddTestHelper<uint8_t>();
385*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyAddTestHelper<uint16_t>();
386*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyAddTestHelper<uint32_t>();
387*9880d681SAndroid Build Coastguard Worker SaturatingMultiplyAddTestHelper<uint64_t>();
388*9880d681SAndroid Build Coastguard Worker }
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker }
391