Support: Extract ScaledNumbers::getSum() and getDifference()

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211553 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith
2014-06-23 23:15:25 +00:00
parent 465f06cfa6
commit 558b7725b7
3 changed files with 250 additions and 61 deletions

View File

@ -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