diff options
author | Tim Shen <timshen91@gmail.com> | 2018-06-25 23:49:20 +0000 |
---|---|---|
committer | Tim Shen <timshen91@gmail.com> | 2018-06-25 23:49:20 +0000 |
commit | 802c31cc283e7cb85a9eddc19a82af9f0602077d (patch) | |
tree | b6d42f4a63a8b4fec6b1632ae6e0862b2e92846f /llvm/lib/Support/APInt.cpp | |
parent | 32a914256e6a8e8d1b2c78c71def1d9cb7042371 (diff) | |
download | bcm5719-llvm-802c31cc283e7cb85a9eddc19a82af9f0602077d.tar.gz bcm5719-llvm-802c31cc283e7cb85a9eddc19a82af9f0602077d.zip |
[APInt] Add helpers for rounding u/sdivs.
Reviewers: sanjoy, craig.topper
Subscribers: jlebar, hiraditya, bixia, llvm-commits
Differential Revision: https://reviews.llvm.org/D48498
llvm-svn: 335557
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 2c2ce9588a2..8be903f2ccb 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -2658,3 +2658,49 @@ void APInt::tcSetLeastSignificantBits(WordType *dst, unsigned parts, while (i < parts) dst[i++] = 0; } + +APInt llvm::APIntOps::RoundingUDiv(const APInt &A, const APInt &B, + APInt::Rounding RM) { + // Currently udivrem always rounds down. + switch (RM) { + case APInt::Rounding::DOWN: + case APInt::Rounding::TOWARD_ZERO: + return A.udiv(B); + case APInt::Rounding::UP: { + APInt Quo, Rem; + APInt::udivrem(A, B, Quo, Rem); + if (Rem == 0) + return Quo; + return Quo + 1; + } + } +} + +APInt llvm::APIntOps::RoundingSDiv(const APInt &A, const APInt &B, + APInt::Rounding RM) { + switch (RM) { + case APInt::Rounding::DOWN: + case APInt::Rounding::UP: { + APInt Quo, Rem; + APInt::sdivrem(A, B, Quo, Rem); + if (Rem == 0) + return Quo; + // This algorithm deals with arbitrary rounding mode used by sdivrem. + // We want to check whether the non-integer part of the mathematical value + // is negative or not. If the non-integer part is negative, we need to round + // down from Quo; otherwise, if it's positive or 0, we return Quo, as it's + // already rounded down. + if (RM == APInt::Rounding::DOWN) { + if (Rem.isNegative() != B.isNegative()) + return Quo - 1; + return Quo; + } + if (Rem.isNegative() != B.isNegative()) + return Quo; + return Quo + 1; + } + // Currently sdiv rounds twards zero. + case APInt::Rounding::TOWARD_ZERO: + return A.sdiv(B); + } +} |