X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=unittests%2FSupport%2FMathExtrasTest.cpp;h=fa12f750407badf90af4fdc0f547fb8d42602755;hp=1f1946827e37695fb673d5310bafb2ab549601a4;hb=f2bc179203d0e17bfcfa28bd5b9c1ba1d04cd6fe;hpb=dcafd041638eac9c062c23384562421dba742d83 diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp index 1f1946827e3..fa12f750407 100644 --- a/unittests/Support/MathExtrasTest.cpp +++ b/unittests/Support/MathExtrasTest.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/Support/MathExtrasTest.cpp - math utils tests --------===// +//===- unittests/Support/MathExtrasTest.cpp - math utils tests ------------===// // // The LLVM Compiler Infrastructure // @@ -14,6 +14,109 @@ using namespace llvm; namespace { +TEST(MathExtras, countTrailingZeros) { + uint8_t Z8 = 0; + uint16_t Z16 = 0; + uint32_t Z32 = 0; + uint64_t Z64 = 0; + EXPECT_EQ(8u, countTrailingZeros(Z8)); + EXPECT_EQ(16u, countTrailingZeros(Z16)); + EXPECT_EQ(32u, countTrailingZeros(Z32)); + EXPECT_EQ(64u, countTrailingZeros(Z64)); + + uint8_t NZ8 = 42; + uint16_t NZ16 = 42; + uint32_t NZ32 = 42; + uint64_t NZ64 = 42; + EXPECT_EQ(1u, countTrailingZeros(NZ8)); + EXPECT_EQ(1u, countTrailingZeros(NZ16)); + EXPECT_EQ(1u, countTrailingZeros(NZ32)); + EXPECT_EQ(1u, countTrailingZeros(NZ64)); +} + +TEST(MathExtras, countLeadingZeros) { + uint8_t Z8 = 0; + uint16_t Z16 = 0; + uint32_t Z32 = 0; + uint64_t Z64 = 0; + EXPECT_EQ(8u, countLeadingZeros(Z8)); + EXPECT_EQ(16u, countLeadingZeros(Z16)); + EXPECT_EQ(32u, countLeadingZeros(Z32)); + EXPECT_EQ(64u, countLeadingZeros(Z64)); + + uint8_t NZ8 = 42; + uint16_t NZ16 = 42; + uint32_t NZ32 = 42; + uint64_t NZ64 = 42; + EXPECT_EQ(2u, countLeadingZeros(NZ8)); + EXPECT_EQ(10u, countLeadingZeros(NZ16)); + EXPECT_EQ(26u, countLeadingZeros(NZ32)); + EXPECT_EQ(58u, countLeadingZeros(NZ64)); + + EXPECT_EQ(8u, countLeadingZeros(0x00F000FFu)); + EXPECT_EQ(8u, countLeadingZeros(0x00F12345u)); + for (unsigned i = 0; i <= 30; ++i) { + EXPECT_EQ(31 - i, countLeadingZeros(1u << i)); + } + + EXPECT_EQ(8u, countLeadingZeros(0x00F1234500F12345ULL)); + EXPECT_EQ(1u, countLeadingZeros(1ULL << 62)); + for (unsigned i = 0; i <= 62; ++i) { + EXPECT_EQ(63 - i, countLeadingZeros(1ULL << i)); + } +} + +TEST(MathExtras, findFirstSet) { + uint8_t Z8 = 0; + uint16_t Z16 = 0; + uint32_t Z32 = 0; + uint64_t Z64 = 0; + EXPECT_EQ(0xFFULL, findFirstSet(Z8)); + EXPECT_EQ(0xFFFFULL, findFirstSet(Z16)); + EXPECT_EQ(0xFFFFFFFFULL, findFirstSet(Z32)); + EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, findFirstSet(Z64)); + + uint8_t NZ8 = 42; + uint16_t NZ16 = 42; + uint32_t NZ32 = 42; + uint64_t NZ64 = 42; + EXPECT_EQ(1u, findFirstSet(NZ8)); + EXPECT_EQ(1u, findFirstSet(NZ16)); + EXPECT_EQ(1u, findFirstSet(NZ32)); + EXPECT_EQ(1u, findFirstSet(NZ64)); +} + +TEST(MathExtras, findLastSet) { + uint8_t Z8 = 0; + uint16_t Z16 = 0; + uint32_t Z32 = 0; + uint64_t Z64 = 0; + EXPECT_EQ(0xFFULL, findLastSet(Z8)); + EXPECT_EQ(0xFFFFULL, findLastSet(Z16)); + EXPECT_EQ(0xFFFFFFFFULL, findLastSet(Z32)); + EXPECT_EQ(0xFFFFFFFFFFFFFFFFULL, findLastSet(Z64)); + + uint8_t NZ8 = 42; + uint16_t NZ16 = 42; + uint32_t NZ32 = 42; + uint64_t NZ64 = 42; + EXPECT_EQ(5u, findLastSet(NZ8)); + EXPECT_EQ(5u, findLastSet(NZ16)); + EXPECT_EQ(5u, findLastSet(NZ32)); + EXPECT_EQ(5u, findLastSet(NZ64)); +} + +TEST(MathExtras, reverseBits) { + uint8_t NZ8 = 42; + uint16_t NZ16 = 42; + uint32_t NZ32 = 42; + uint64_t NZ64 = 42; + EXPECT_EQ(0x54ULL, reverseBits(NZ8)); + EXPECT_EQ(0x5400ULL, reverseBits(NZ16)); + EXPECT_EQ(0x54000000ULL, reverseBits(NZ32)); + EXPECT_EQ(0x5400000000000000ULL, reverseBits(NZ64)); +} + TEST(MathExtras, isPowerOf2_32) { EXPECT_TRUE(isPowerOf2_32(1 << 6)); EXPECT_TRUE(isPowerOf2_32(1 << 12)); @@ -38,42 +141,23 @@ TEST(MathExtras, ByteSwap_64) { EXPECT_EQ(0x1100FFEEDDCCBBAAULL, ByteSwap_64(0xAABBCCDDEEFF0011LL)); } -TEST(MathExtras, CountLeadingZeros_32) { - EXPECT_EQ(8u, CountLeadingZeros_32(0x00F000FF)); - EXPECT_EQ(8u, CountLeadingZeros_32(0x00F12345)); - for (unsigned i = 0; i <= 30; ++i) { - EXPECT_EQ(31 - i, CountLeadingZeros_32(1 << i)); - } -} - -TEST(MathExtras, CountLeadingZeros_64) { - EXPECT_EQ(8u, CountLeadingZeros_64(0x00F1234500F12345LL)); - EXPECT_EQ(1u, CountLeadingZeros_64(1LL << 62)); - for (unsigned i = 0; i <= 62; ++i) { - EXPECT_EQ(63 - i, CountLeadingZeros_64(1LL << i)); - } -} - -TEST(MathExtras, CountLeadingOnes_32) { +TEST(MathExtras, countLeadingOnes) { for (int i = 30; i >= 0; --i) { // Start with all ones and unset some bit. - EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i))); + EXPECT_EQ(31u - i, countLeadingOnes(0xFFFFFFFF ^ (1 << i))); } -} - -TEST(MathExtras, CountLeadingOnes_64) { for (int i = 62; i >= 0; --i) { // Start with all ones and unset some bit. - EXPECT_EQ(63u - i, CountLeadingOnes_64(0xFFFFFFFFFFFFFFFFLL ^ (1LL << i))); + EXPECT_EQ(63u - i, countLeadingOnes(0xFFFFFFFFFFFFFFFFULL ^ (1LL << i))); } for (int i = 30; i >= 0; --i) { // Start with all ones and unset some bit. - EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i))); + EXPECT_EQ(31u - i, countLeadingOnes(0xFFFFFFFF ^ (1 << i))); } } TEST(MathExtras, FloatBits) { - static const float kValue = 5632.34; + static const float kValue = 5632.34f; EXPECT_FLOAT_EQ(kValue, BitsToFloat(FloatToBits(kValue))); } @@ -99,6 +183,76 @@ TEST(MathExtras, RoundUpToAlignment) { EXPECT_EQ(8u, RoundUpToAlignment(5, 8)); EXPECT_EQ(24u, RoundUpToAlignment(17, 8)); EXPECT_EQ(0u, RoundUpToAlignment(~0LL, 8)); + + EXPECT_EQ(7u, RoundUpToAlignment(5, 8, 7)); + EXPECT_EQ(17u, RoundUpToAlignment(17, 8, 1)); + EXPECT_EQ(3u, RoundUpToAlignment(~0LL, 8, 3)); + EXPECT_EQ(552u, RoundUpToAlignment(321, 255, 42)); +} + +template +void SaturatingAddTestHelper() +{ + const T Max = std::numeric_limits::max(); + EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2))); + EXPECT_EQ(Max, SaturatingAdd(Max, T(1))); + EXPECT_EQ(Max, SaturatingAdd(T(1), Max)); + EXPECT_EQ(Max, SaturatingAdd(Max, Max)); +} + +TEST(MathExtras, SaturatingAdd) { + SaturatingAddTestHelper(); + SaturatingAddTestHelper(); + SaturatingAddTestHelper(); + SaturatingAddTestHelper(); +} + +template +void SaturatingMultiplyTestHelper() +{ + const T Max = std::numeric_limits::max(); + + // Test basic multiplication. + EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3))); + EXPECT_EQ(T(6), SaturatingMultiply(T(3), T(2))); + + // Test multiplication by zero. + EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(0))); + EXPECT_EQ(T(0), SaturatingMultiply(T(1), T(0))); + EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(1))); + EXPECT_EQ(T(0), SaturatingMultiply(Max, T(0))); + EXPECT_EQ(T(0), SaturatingMultiply(T(0), Max)); + + // Test multiplication by maximum value. + EXPECT_EQ(Max, SaturatingMultiply(Max, T(2))); + EXPECT_EQ(Max, SaturatingMultiply(T(2),Max)); + EXPECT_EQ(Max, SaturatingMultiply(Max, Max)); + + // Test interesting boundary conditions for algorithm - + // ((1 << A) - 1) * ((1 << B) + K) for K in [-1, 0, 1] + // and A + B == std::numeric_limits::digits. + // We expect overflow iff A > B and K = 1. + const int Digits = std::numeric_limits::digits; + for (int A = 1, B = Digits - 1; B >= 1; ++A, --B) { + for (int K = -1; K <= 1; ++K) { + T X = (T(1) << A) - T(1); + T Y = (T(1) << B) + K; + bool OverflowExpected = A > B && K == 1; + + if(OverflowExpected) { + EXPECT_EQ(Max, SaturatingMultiply(X, Y)); + } else { + EXPECT_EQ(X * Y, SaturatingMultiply(X, Y)); + } + } + } +} + +TEST(MathExtras, SaturatingMultiply) { + SaturatingMultiplyTestHelper(); + SaturatingMultiplyTestHelper(); + SaturatingMultiplyTestHelper(); + SaturatingMultiplyTestHelper(); } }