From 706b4fc47bbc608932d3b491ae19a3b9cde9497b Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 17 Jan 2020 20:45:01 +0000 Subject: Vendor import of llvm-project master e26a78e70, the last commit before the llvmorg-11-init tag, from which release/10.x was branched. --- llvm/lib/Support/APInt.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) (limited to 'llvm/lib/Support/APInt.cpp') diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 758fe8b4f866..9b9cd70078b3 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -187,7 +187,7 @@ APInt& APInt::operator--() { return clearUnusedBits(); } -/// Adds the RHS APint to this APInt. +/// Adds the RHS APInt to this APInt. /// @returns this, after addition of RHS. /// Addition assignment operator. APInt& APInt::operator+=(const APInt& RHS) { @@ -884,6 +884,31 @@ APInt APInt::trunc(unsigned width) const { return Result; } +// Truncate to new width with unsigned saturation. +APInt APInt::truncUSat(unsigned width) const { + assert(width < BitWidth && "Invalid APInt Truncate request"); + assert(width && "Can't truncate to 0 bits"); + + // Can we just losslessly truncate it? + if (isIntN(width)) + return trunc(width); + // If not, then just return the new limit. + return APInt::getMaxValue(width); +} + +// Truncate to new width with signed saturation. +APInt APInt::truncSSat(unsigned width) const { + assert(width < BitWidth && "Invalid APInt Truncate request"); + assert(width && "Can't truncate to 0 bits"); + + // Can we just losslessly truncate it? + if (isSignedIntN(width)) + return trunc(width); + // If not, then just return the new limits. + return isNegative() ? APInt::getSignedMinValue(width) + : APInt::getSignedMaxValue(width); +} + // Sign extend to a new width. APInt APInt::sext(unsigned Width) const { assert(Width > BitWidth && "Invalid APInt SignExtend request"); @@ -2048,6 +2073,46 @@ APInt APInt::usub_sat(const APInt &RHS) const { return APInt(BitWidth, 0); } +APInt APInt::smul_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = smul_ov(RHS, Overflow); + if (!Overflow) + return Res; + + // The result is negative if one and only one of inputs is negative. + bool ResIsNegative = isNegative() ^ RHS.isNegative(); + + return ResIsNegative ? APInt::getSignedMinValue(BitWidth) + : APInt::getSignedMaxValue(BitWidth); +} + +APInt APInt::umul_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = umul_ov(RHS, Overflow); + if (!Overflow) + return Res; + + return APInt::getMaxValue(BitWidth); +} + +APInt APInt::sshl_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = sshl_ov(RHS, Overflow); + if (!Overflow) + return Res; + + return isNegative() ? APInt::getSignedMinValue(BitWidth) + : APInt::getSignedMaxValue(BitWidth); +} + +APInt APInt::ushl_sat(const APInt &RHS) const { + bool Overflow; + APInt Res = ushl_ov(RHS, Overflow); + if (!Overflow) + return Res; + + return APInt::getMaxValue(BitWidth); +} void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) { // Check our assumptions here @@ -2790,7 +2855,7 @@ APInt llvm::APIntOps::RoundingSDiv(const APInt &A, const APInt &B, return Quo; return Quo + 1; } - // Currently sdiv rounds twards zero. + // Currently sdiv rounds towards zero. case APInt::Rounding::TOWARD_ZERO: return A.sdiv(B); } @@ -2933,7 +2998,7 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, APInt Q = SQ * SQ; bool InexactSQ = Q != D; // The calculated SQ may actually be greater than the exact (non-integer) - // value. If that's the case, decremement SQ to get a value that is lower. + // value. If that's the case, decrement SQ to get a value that is lower. if (Q.sgt(D)) SQ -= 1; @@ -2987,6 +3052,14 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, return X; } +Optional +llvm::APIntOps::GetMostSignificantDifferentBit(const APInt &A, const APInt &B) { + assert(A.getBitWidth() == B.getBitWidth() && "Must have the same bitwidth"); + if (A == B) + return llvm::None; + return A.getBitWidth() - ((A ^ B).countLeadingZeros() + 1); +} + /// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst /// with the integer held in IntVal. void llvm::StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, -- cgit v1.2.3