summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorTim Shen <timshen91@gmail.com>2018-06-25 23:49:20 +0000
committerTim Shen <timshen91@gmail.com>2018-06-25 23:49:20 +0000
commit802c31cc283e7cb85a9eddc19a82af9f0602077d (patch)
treeb6d42f4a63a8b4fec6b1632ae6e0862b2e92846f /llvm/lib/Support/APInt.cpp
parent32a914256e6a8e8d1b2c78c71def1d9cb7042371 (diff)
downloadbcm5719-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.cpp46
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);
+ }
+}
OpenPOWER on IntegriCloud