Index: include/llvm/ProfileData/InstrProf.h =================================================================== --- include/llvm/ProfileData/InstrProf.h +++ include/llvm/ProfileData/InstrProf.h @@ -443,11 +443,11 @@ bool ResultOverflowed; uint64_t OtherCount = Other.Counts[I]; if (Weight > 1) { - OtherCount = SaturatingMultiply(OtherCount, Weight, ResultOverflowed); + OtherCount = SaturatingMultiply(OtherCount, Weight, &ResultOverflowed); if (ResultOverflowed) Result = instrprof_error::counter_overflow; } - Counts[I] = SaturatingAdd(Counts[I], OtherCount, ResultOverflowed); + Counts[I] = SaturatingAdd(Counts[I], OtherCount, &ResultOverflowed); if (ResultOverflowed) Result = instrprof_error::counter_overflow; } Index: include/llvm/Support/MathExtras.h =================================================================== --- include/llvm/Support/MathExtras.h +++ include/llvm/Support/MathExtras.h @@ -659,38 +659,34 @@ /// representable value of type T. template typename std::enable_if::value, T>::type -SaturatingAdd(T X, T Y, bool &ResultOverflowed) { +SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) { + bool Dummy; + bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; // Hacker's Delight, p. 29 T Z = X + Y; - ResultOverflowed = (Z < X || Z < Y); - if (ResultOverflowed) + Overflowed = (Z < X || Z < Y); + if (Overflowed) return std::numeric_limits::max(); else return Z; } -/// \brief Add two unsigned integers, X and Y, of type T. -/// Clamp the result to the maximum representable value of T on overflow. -template -typename std::enable_if::value, T>::type -SaturatingAdd(T X, T Y) { - bool ResultOverflowed; - return SaturatingAdd(X, Y, ResultOverflowed); -} - /// \brief Multiply two unsigned integers, X and Y, of type T. /// Clamp the result to the maximum representable value of T on overflow. /// ResultOverflowed indicates if the result is larger than the maximum /// representable value of type T. template typename std::enable_if::value, T>::type -SaturatingMultiply(T X, T Y, bool &ResultOverflowed) { +SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) { + bool Dummy; + bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy; + // Hacker's Delight, p. 30 has a different algorithm, but we don't use that // because it fails for uint16_t (where multiplication can have undefined // behavior due to promotion to int), and requires a division in addition // to the multiplication. - ResultOverflowed = false; + Overflowed = false; // Log2(Z) would be either Log2Z or Log2Z + 1. // Special case: if X or Y is 0, Log2_64 gives -1, and Log2Z @@ -702,7 +698,7 @@ return X * Y; } if (Log2Z > Log2Max) { - ResultOverflowed = true; + Overflowed = true; return Max; } @@ -711,7 +707,7 @@ // that on at the end. T Z = (X >> 1) * Y; if (Z & ~(Max >> 1)) { - ResultOverflowed = true; + Overflowed = true; return Max; } Z <<= 1; @@ -721,15 +717,6 @@ return Z; } -/// \brief Multiply two unsigned integers, X and Y, of type T. -/// Clamp the result to the maximum representable value of T on overflow. -template -typename std::enable_if::value, T>::type -SaturatingMultiply(T X, T Y) { - bool ResultOverflowed; - return SaturatingMultiply(X, Y, ResultOverflowed); -} - extern const float huge_valf; } // End llvm namespace Index: lib/ProfileData/InstrProfWriter.cpp =================================================================== --- lib/ProfileData/InstrProfWriter.cpp +++ lib/ProfileData/InstrProfWriter.cpp @@ -117,7 +117,7 @@ if (Weight > 1) { for (auto &Count : Dest.Counts) { bool Overflowed; - Count = SaturatingMultiply(Count, Weight, Overflowed); + Count = SaturatingMultiply(Count, Weight, &Overflowed); if (Overflowed && Result == instrprof_error::success) { Result = instrprof_error::counter_overflow; } Index: unittests/Support/MathExtrasTest.cpp =================================================================== --- unittests/Support/MathExtrasTest.cpp +++ unittests/Support/MathExtrasTest.cpp @@ -197,23 +197,23 @@ bool ResultOverflowed; EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2))); - EXPECT_EQ(T(3), SaturatingAdd(T(1), T(2), ResultOverflowed)); + 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_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_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_EQ(Max, SaturatingAdd(T(1), Max, &ResultOverflowed)); EXPECT_TRUE(ResultOverflowed); EXPECT_EQ(Max, SaturatingAdd(Max, Max)); - EXPECT_EQ(Max, SaturatingAdd(Max, Max, ResultOverflowed)); + EXPECT_EQ(Max, SaturatingAdd(Max, Max, &ResultOverflowed)); EXPECT_TRUE(ResultOverflowed); } @@ -232,45 +232,45 @@ // Test basic multiplication. EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3))); - EXPECT_EQ(T(6), SaturatingMultiply(T(2), T(3), ResultOverflowed)); + 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_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_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_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_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_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_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_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_EQ(Max, SaturatingMultiply(T(2), Max, &ResultOverflowed)); EXPECT_TRUE(ResultOverflowed); EXPECT_EQ(Max, SaturatingMultiply(Max, Max)); - EXPECT_EQ(Max, SaturatingMultiply(Max, Max, ResultOverflowed)); + EXPECT_EQ(Max, SaturatingMultiply(Max, Max, &ResultOverflowed)); EXPECT_TRUE(ResultOverflowed); // Test interesting boundary conditions for algorithm - @@ -286,11 +286,11 @@ if(OverflowExpected) { EXPECT_EQ(Max, SaturatingMultiply(X, Y)); - EXPECT_EQ(Max, SaturatingMultiply(X, Y, ResultOverflowed)); + 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_EQ(X * Y, SaturatingMultiply(X, Y, &ResultOverflowed)); EXPECT_FALSE(ResultOverflowed); } }