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