X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=unittests%2FSupport%2FMathExtrasTest.cpp;h=945d8322b259e07e43efe0cb4fc902e2ca684466;hp=5fd638f5f33692e329cf2c0cc1bedcf441e77bf3;hb=09a7daad01b02482a58fb2ad6972e80871040c84;hpb=36fe3f2b5651882b12e24b49dc7818ebb1a5d79f diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp index 5fd638f5f33..945d8322b25 100644 --- a/unittests/Support/MathExtrasTest.cpp +++ b/unittests/Support/MathExtrasTest.cpp @@ -19,19 +19,19 @@ TEST(MathExtras, countTrailingZeros) { uint16_t Z16 = 0; uint32_t Z32 = 0; uint64_t Z64 = 0; - EXPECT_EQ(8, countTrailingZeros(Z8)); - EXPECT_EQ(16, countTrailingZeros(Z16)); - EXPECT_EQ(32, countTrailingZeros(Z32)); - EXPECT_EQ(64, countTrailingZeros(Z64)); + 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(1, countTrailingZeros(NZ8)); - EXPECT_EQ(1, countTrailingZeros(NZ16)); - EXPECT_EQ(1, countTrailingZeros(NZ32)); - EXPECT_EQ(1, countTrailingZeros(NZ64)); + EXPECT_EQ(1u, countTrailingZeros(NZ8)); + EXPECT_EQ(1u, countTrailingZeros(NZ16)); + EXPECT_EQ(1u, countTrailingZeros(NZ32)); + EXPECT_EQ(1u, countTrailingZeros(NZ64)); } TEST(MathExtras, countLeadingZeros) { @@ -39,19 +39,31 @@ TEST(MathExtras, countLeadingZeros) { uint16_t Z16 = 0; uint32_t Z32 = 0; uint64_t Z64 = 0; - EXPECT_EQ(8, countLeadingZeros(Z8)); - EXPECT_EQ(16, countLeadingZeros(Z16)); - EXPECT_EQ(32, countLeadingZeros(Z32)); - EXPECT_EQ(64, countLeadingZeros(Z64)); + 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(2, countLeadingZeros(NZ8)); - EXPECT_EQ(10, countLeadingZeros(NZ16)); - EXPECT_EQ(26, countLeadingZeros(NZ32)); - EXPECT_EQ(58, countLeadingZeros(NZ64)); + 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) { @@ -59,19 +71,19 @@ TEST(MathExtras, findFirstSet) { uint16_t Z16 = 0; uint32_t Z32 = 0; uint64_t Z64 = 0; - EXPECT_EQ(0xFF, findFirstSet(Z8)); - EXPECT_EQ(0xFFFF, findFirstSet(Z16)); - EXPECT_EQ(0xFFFFFFFF, findFirstSet(Z32)); - EXPECT_EQ(0xFFFFFFFFFFFFFFFF, findFirstSet(Z64)); + 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(1, findFirstSet(NZ8)); - EXPECT_EQ(1, findFirstSet(NZ16)); - EXPECT_EQ(1, findFirstSet(NZ32)); - EXPECT_EQ(1, findFirstSet(NZ64)); + EXPECT_EQ(1u, findFirstSet(NZ8)); + EXPECT_EQ(1u, findFirstSet(NZ16)); + EXPECT_EQ(1u, findFirstSet(NZ32)); + EXPECT_EQ(1u, findFirstSet(NZ64)); } TEST(MathExtras, findLastSet) { @@ -79,19 +91,19 @@ TEST(MathExtras, findLastSet) { uint16_t Z16 = 0; uint32_t Z32 = 0; uint64_t Z64 = 0; - EXPECT_EQ(0xFF, findLastSet(Z8)); - EXPECT_EQ(0xFFFF, findLastSet(Z16)); - EXPECT_EQ(0xFFFFFFFF, findLastSet(Z32)); - EXPECT_EQ(0xFFFFFFFFFFFFFFFF, findLastSet(Z64)); + 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(5, findLastSet(NZ8)); - EXPECT_EQ(5, findLastSet(NZ16)); - EXPECT_EQ(5, findLastSet(NZ32)); - EXPECT_EQ(5, findLastSet(NZ64)); + EXPECT_EQ(5u, findLastSet(NZ8)); + EXPECT_EQ(5u, findLastSet(NZ16)); + EXPECT_EQ(5u, findLastSet(NZ32)); + EXPECT_EQ(5u, findLastSet(NZ64)); } TEST(MathExtras, reverseBits) { @@ -99,10 +111,10 @@ TEST(MathExtras, reverseBits) { uint16_t NZ16 = 42; uint32_t NZ32 = 42; uint64_t NZ64 = 42; - EXPECT_EQ(0x54, reverseBits(NZ8)); - EXPECT_EQ(0x5400, reverseBits(NZ16)); - EXPECT_EQ(0x54000000, reverseBits(NZ32)); - EXPECT_EQ(0x5400000000000000, reverseBits(NZ64)); + EXPECT_EQ(0x54ULL, reverseBits(NZ8)); + EXPECT_EQ(0x5400ULL, reverseBits(NZ16)); + EXPECT_EQ(0x54000000ULL, reverseBits(NZ32)); + EXPECT_EQ(0x5400000000000000ULL, reverseBits(NZ64)); } TEST(MathExtras, isPowerOf2_32) { @@ -129,37 +141,18 @@ 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))); } } @@ -190,6 +183,125 @@ 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(); + bool ResultOverflowed; + + EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2))); + EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(Max, T(1))); + EXPECT_EQ(Max, SaturatingAdd(Max, T(1), &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 1))); + EXPECT_EQ(Max, SaturatingAdd(T(1), T(Max - 1), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(T(1), Max)); + EXPECT_EQ(Max, SaturatingAdd(T(1), Max, &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingAdd(Max, Max)); + EXPECT_EQ(Max, SaturatingAdd(Max, Max, &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); +} + +TEST(MathExtras, SaturatingAdd) { + SaturatingAddTestHelper(); + SaturatingAddTestHelper(); + SaturatingAddTestHelper(); + SaturatingAddTestHelper(); +} + +template +void SaturatingMultiplyTestHelper() +{ + const T Max = std::numeric_limits::max(); + bool ResultOverflowed; + + // Test basic multiplication. + EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3))); + EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(T(6), SaturatingMultiply(T(3), T(2))); + EXPECT_EQ(T(6), SaturatingMultiply(T(3), T(2), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + // Test multiplication by zero. + EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(0))); + EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(0), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(T(0), SaturatingMultiply(T(1), T(0))); + EXPECT_EQ(T(0), SaturatingMultiply(T(1), T(0), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(1))); + EXPECT_EQ(T(0), SaturatingMultiply(T(0), T(1), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(T(0), SaturatingMultiply(Max, T(0))); + EXPECT_EQ(T(0), SaturatingMultiply(Max, T(0), &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + EXPECT_EQ(T(0), SaturatingMultiply(T(0), Max)); + EXPECT_EQ(T(0), SaturatingMultiply(T(0), Max, &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + + // Test multiplication by maximum value. + EXPECT_EQ(Max, SaturatingMultiply(Max, T(2))); + EXPECT_EQ(Max, SaturatingMultiply(Max, T(2), &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingMultiply(T(2), Max)); + EXPECT_EQ(Max, SaturatingMultiply(T(2), Max, &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + + EXPECT_EQ(Max, SaturatingMultiply(Max, Max)); + EXPECT_EQ(Max, SaturatingMultiply(Max, Max, &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + + // 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)); + EXPECT_EQ(Max, SaturatingMultiply(X, Y, &ResultOverflowed)); + EXPECT_TRUE(ResultOverflowed); + } else { + EXPECT_EQ(X * Y, SaturatingMultiply(X, Y)); + EXPECT_EQ(X * Y, SaturatingMultiply(X, Y, &ResultOverflowed)); + EXPECT_FALSE(ResultOverflowed); + } + } + } +} + +TEST(MathExtras, SaturatingMultiply) { + SaturatingMultiplyTestHelper(); + SaturatingMultiplyTestHelper(); + SaturatingMultiplyTestHelper(); + SaturatingMultiplyTestHelper(); } }