From 558b7725b77d0bd8231b34dcc6f8904e5d1e5b8d Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 23 Jun 2014 23:15:25 +0000 Subject: Support: Extract ScaledNumbers::getSum() and getDifference() git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211553 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/Support/ScaledNumberTest.cpp | 150 +++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) (limited to 'unittests') diff --git a/unittests/Support/ScaledNumberTest.cpp b/unittests/Support/ScaledNumberTest.cpp index 08d6c68b0e..48527e5d1b 100644 --- a/unittests/Support/ScaledNumberTest.cpp +++ b/unittests/Support/ScaledNumberTest.cpp @@ -386,4 +386,154 @@ TEST(ScaledNumberHelpersTest, matchScales) { MATCH_SCALES(uint64_t, 9, 0, UINT64_C(1) << 59, 4, 9, UINT64_C(1) << 63, 0); } +TEST(ScaledNumberHelpersTest, getSum) { + // Zero. + EXPECT_EQ(SP32(1, 0), getSum32(0, 0, 1, 0)); + EXPECT_EQ(SP32(8, -3), getSum32(0, 0, 8, -3)); + EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(0, 0, UINT32_MAX, 0)); + + // Basic. + EXPECT_EQ(SP32(2, 0), getSum32(1, 0, 1, 0)); + EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 2, 0)); + EXPECT_EQ(SP32(67, 0), getSum32(7, 0, 60, 0)); + + // Different scales. + EXPECT_EQ(SP32(3, 0), getSum32(1, 0, 1, 1)); + EXPECT_EQ(SP32(4, 0), getSum32(2, 0, 1, 1)); + + // Loss of precision. + EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 32, 1, 0)); + EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, -32, 1, 0)); + + // Not quite loss of precision. + EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 32, 1, 1)); + EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -32, 1, -1)); + + // Overflow. + EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, UINT32_MAX, 0)); + + // Reverse operand order. + EXPECT_EQ(SP32(1, 0), getSum32(1, 0, 0, 0)); + EXPECT_EQ(SP32(8, -3), getSum32(8, -3, 0, 0)); + EXPECT_EQ(SP32(UINT32_MAX, 0), getSum32(UINT32_MAX, 0, 0, 0)); + EXPECT_EQ(SP32(3, 0), getSum32(2, 0, 1, 0)); + EXPECT_EQ(SP32(67, 0), getSum32(60, 0, 7, 0)); + EXPECT_EQ(SP32(3, 0), getSum32(1, 1, 1, 0)); + EXPECT_EQ(SP32(4, 0), getSum32(1, 1, 2, 0)); + EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(1, 0, 1, 32)); + EXPECT_EQ(SP32(UINT32_C(1) << 31, -31), getSum32(1, 0, 1, -32)); + EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), getSum32(1, 1, 1, 32)); + EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -32), getSum32(1, -1, 1, -32)); + EXPECT_EQ(SP32(UINT32_C(1) << 31, 1), getSum32(UINT32_MAX, 0, 1, 0)); + + // Zero. + EXPECT_EQ(SP64(1, 0), getSum64(0, 0, 1, 0)); + EXPECT_EQ(SP64(8, -3), getSum64(0, 0, 8, -3)); + EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(0, 0, UINT64_MAX, 0)); + + // Basic. + EXPECT_EQ(SP64(2, 0), getSum64(1, 0, 1, 0)); + EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 2, 0)); + EXPECT_EQ(SP64(67, 0), getSum64(7, 0, 60, 0)); + + // Different scales. + EXPECT_EQ(SP64(3, 0), getSum64(1, 0, 1, 1)); + EXPECT_EQ(SP64(4, 0), getSum64(2, 0, 1, 1)); + + // Loss of precision. + EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 64, 1, 0)); + EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, -64, 1, 0)); + + // Not quite loss of precision. + EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 64, 1, 1)); + EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -64, 1, -1)); + + // Overflow. + EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, UINT64_MAX, 0)); + + // Reverse operand order. + EXPECT_EQ(SP64(1, 0), getSum64(1, 0, 0, 0)); + EXPECT_EQ(SP64(8, -3), getSum64(8, -3, 0, 0)); + EXPECT_EQ(SP64(UINT64_MAX, 0), getSum64(UINT64_MAX, 0, 0, 0)); + EXPECT_EQ(SP64(3, 0), getSum64(2, 0, 1, 0)); + EXPECT_EQ(SP64(67, 0), getSum64(60, 0, 7, 0)); + EXPECT_EQ(SP64(3, 0), getSum64(1, 1, 1, 0)); + EXPECT_EQ(SP64(4, 0), getSum64(1, 1, 2, 0)); + EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(1, 0, 1, 64)); + EXPECT_EQ(SP64(UINT64_C(1) << 63, -63), getSum64(1, 0, 1, -64)); + EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), getSum64(1, 1, 1, 64)); + EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -64), getSum64(1, -1, 1, -64)); + EXPECT_EQ(SP64(UINT64_C(1) << 63, 1), getSum64(UINT64_MAX, 0, 1, 0)); +} + +TEST(ScaledNumberHelpersTest, getDifference) { + // Basic. + EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 0)); + EXPECT_EQ(SP32(1, 0), getDifference32(2, 0, 1, 0)); + EXPECT_EQ(SP32(53, 0), getDifference32(60, 0, 7, 0)); + + // Equals "0", different scales. + EXPECT_EQ(SP32(0, 0), getDifference32(2, 0, 1, 1)); + + // Subtract "0". + EXPECT_EQ(SP32(1, 0), getDifference32(1, 0, 0, 0)); + EXPECT_EQ(SP32(8, -3), getDifference32(8, -3, 0, 0)); + EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(UINT32_MAX, 0, 0, 0)); + + // Loss of precision. + EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, 1), + getDifference32((UINT32_C(1) << 31) + 1, 1, 1, 0)); + EXPECT_EQ(SP32((UINT32_C(1) << 31) + 1, -31), + getDifference32((UINT32_C(1) << 31) + 1, -31, 1, -32)); + + // Not quite loss of precision. + EXPECT_EQ(SP32(UINT32_MAX, 0), getDifference32(1, 32, 1, 0)); + EXPECT_EQ(SP32(UINT32_MAX, -32), getDifference32(1, 0, 1, -32)); + + // Saturate to "0". + EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 1, 0)); + EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, 8, -3)); + EXPECT_EQ(SP32(0, 0), getDifference32(0, 0, UINT32_MAX, 0)); + EXPECT_EQ(SP32(0, 0), getDifference32(7, 0, 60, 0)); + EXPECT_EQ(SP32(0, 0), getDifference32(1, 0, 1, 1)); + EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, 0)); + EXPECT_EQ(SP32(0, 0), getDifference32(1, -32, 1, -1)); + + // Regression tests for cases that failed during bringup. + EXPECT_EQ(SP32(UINT32_C(1) << 26, -31), + getDifference32(1, 0, UINT32_C(31) << 27, -32)); + + // Basic. + EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 0)); + EXPECT_EQ(SP64(1, 0), getDifference64(2, 0, 1, 0)); + EXPECT_EQ(SP64(53, 0), getDifference64(60, 0, 7, 0)); + + // Equals "0", different scales. + EXPECT_EQ(SP64(0, 0), getDifference64(2, 0, 1, 1)); + + // Subtract "0". + EXPECT_EQ(SP64(1, 0), getDifference64(1, 0, 0, 0)); + EXPECT_EQ(SP64(8, -3), getDifference64(8, -3, 0, 0)); + EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(UINT64_MAX, 0, 0, 0)); + + // Loss of precision. + EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, 1), + getDifference64((UINT64_C(1) << 63) + 1, 1, 1, 0)); + EXPECT_EQ(SP64((UINT64_C(1) << 63) + 1, -63), + getDifference64((UINT64_C(1) << 63) + 1, -63, 1, -64)); + + // Not quite loss of precision. + EXPECT_EQ(SP64(UINT64_MAX, 0), getDifference64(1, 64, 1, 0)); + EXPECT_EQ(SP64(UINT64_MAX, -64), getDifference64(1, 0, 1, -64)); + + // Saturate to "0". + EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 1, 0)); + EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, 8, -3)); + EXPECT_EQ(SP64(0, 0), getDifference64(0, 0, UINT64_MAX, 0)); + EXPECT_EQ(SP64(0, 0), getDifference64(7, 0, 60, 0)); + EXPECT_EQ(SP64(0, 0), getDifference64(1, 0, 1, 1)); + EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, 0)); + EXPECT_EQ(SP64(0, 0), getDifference64(1, -64, 1, -1)); +} + } // end namespace -- cgit v1.2.3