From 68a5ef1a63fdf9f2b15bd3dc98a40b19eb05d56a Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 23 Jun 2014 23:14:51 +0000 Subject: [PATCH] Support: Return scale from ScaledNumbers::matchScales() This will be convenient when extracting `ScaledNumbers::getSum()`. llvm-svn: 211552 --- llvm/include/llvm/Support/ScaledNumber.h | 29 ++++++++++++--------- llvm/unittests/Support/ScaledNumberTest.cpp | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/Support/ScaledNumber.h b/llvm/include/llvm/Support/ScaledNumber.h index b1f6eadab842..caca5f731d48 100644 --- a/llvm/include/llvm/Support/ScaledNumber.h +++ b/llvm/include/llvm/Support/ScaledNumber.h @@ -271,28 +271,30 @@ int compare(DigitsT LDigits, int16_t LScale, DigitsT RDigits, int16_t RScale) { /// losing precision only when necessary. /// /// If the output value of \c LDigits (\c RDigits) is \c 0, the output value of -/// \c LScale (\c RScale) is unspecified. If both \c LDigits and \c RDigits -/// are \c 0, the output value is one of \c LScale and \c RScale; which is -/// unspecified. +/// \c LScale (\c RScale) is unspecified. +/// +/// As a convenience, returns the matching scale. If the output value of one +/// number is zero, returns the scale of the other. If both are zero, which +/// scale is returned is unspecifed. template -void matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits, - int16_t &RScale) { +int16_t matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits, + int16_t &RScale) { static_assert(!std::numeric_limits::is_signed, "expected unsigned"); - if (LScale < RScale) { + if (LScale < RScale) // Swap arguments. - matchScales(RDigits, RScale, LDigits, LScale); - return; - } - if (!LDigits || !RDigits || LScale == RScale) - return; + return matchScales(RDigits, RScale, LDigits, LScale); + if (!LDigits) + return RScale; + if (!RDigits || LScale == RScale) + return LScale; // Now LScale > RScale. Get the difference. int32_t ScaleDiff = int32_t(LScale) - RScale; if (ScaleDiff >= 2 * getWidth()) { // Don't bother shifting. RDigits will get zero-ed out anyway. RDigits = 0; - return; + return LScale; } // Shift LDigits left as much as possible, then shift RDigits right. @@ -303,7 +305,7 @@ void matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits, if (ShiftR >= getWidth()) { // Don't bother shifting. RDigits will get zero-ed out anyway. RDigits = 0; - return; + return LScale; } LDigits <<= ShiftL; @@ -312,6 +314,7 @@ void matchScales(DigitsT &LDigits, int16_t &LScale, DigitsT &RDigits, LScale -= ShiftL; RScale += ShiftR; assert(LScale == RScale && "scales should match"); + return LScale; } } // end namespace ScaledNumbers diff --git a/llvm/unittests/Support/ScaledNumberTest.cpp b/llvm/unittests/Support/ScaledNumberTest.cpp index 550947b8ea3f..08d6c68b0e06 100644 --- a/llvm/unittests/Support/ScaledNumberTest.cpp +++ b/llvm/unittests/Support/ScaledNumberTest.cpp @@ -336,7 +336,7 @@ TEST(ScaledNumberHelpersTest, matchScales) { int16_t RSx = RSIn; \ int16_t Sy = SOut; \ \ - matchScales(LDx, LSx, RDx, RSx); \ + EXPECT_EQ(SOut, matchScales(LDx, LSx, RDx, RSx)); \ EXPECT_EQ(LDy, LDx); \ EXPECT_EQ(RDy, RDx); \ if (LDy) \