11 #include "llvm/ADT/APInt.h"
12 #include "llvm/ADT/Hashing.h"
13 #include "llvm/ADT/STLFunctionalExtras.h"
14 #include "llvm/Support/raw_ostream.h"
21 using namespace presburger;
22 using namespace detail;
28 SlowMPInt::operator int64_t()
const {
return val.getSExtValue(); }
51 return a += SlowMPInt(b);
54 return a -= SlowMPInt(b);
57 return a *= SlowMPInt(b);
60 return a /= SlowMPInt(b);
63 return a %= SlowMPInt(b);
67 return a == SlowMPInt(b);
70 return a != SlowMPInt(b);
73 return a > SlowMPInt(b);
76 return a < SlowMPInt(b);
79 return a <= SlowMPInt(b);
82 return a >= SlowMPInt(b);
85 return a + SlowMPInt(b);
88 return a - SlowMPInt(b);
91 return a * SlowMPInt(b);
94 return a / SlowMPInt(b);
97 return a % SlowMPInt(b);
101 return SlowMPInt(a) == b;
104 return SlowMPInt(a) != b;
107 return SlowMPInt(a) > b;
110 return SlowMPInt(a) < b;
113 return SlowMPInt(a) <= b;
116 return SlowMPInt(a) >= b;
119 return SlowMPInt(a) + b;
122 return SlowMPInt(a) - b;
125 return SlowMPInt(a) * b;
128 return SlowMPInt(a) / b;
131 return SlowMPInt(a) % b;
135 return std::max(a.getBitWidth(), b.getBitWidth());
145 return val.sext(width) == o.val.sext(width);
149 return val.sext(width) != o.val.sext(width);
153 return val.sext(width).sgt(o.val.sext(width));
157 return val.sext(width).slt(o.val.sext(width));
161 return val.sext(width).sle(o.val.sext(width));
165 return val.sext(width).sge(o.val.sext(width));
177 const APInt &a,
const APInt &b,
182 APInt ret = op(a.sext(width), b.sext(width), overflow);
187 ret = op(a.sext(width), b.sext(width), overflow);
188 assert(!overflow &&
"double width should be sufficient to avoid overflow!");
209 SlowMPInt
detail::ceilDiv(
const SlowMPInt &lhs,
const SlowMPInt &rhs) {
213 return SlowMPInt(llvm::APIntOps::RoundingSDiv(
214 lhs.val.sext(width), rhs.val.sext(width), APInt::Rounding::UP));
220 return SlowMPInt(llvm::APIntOps::RoundingSDiv(
221 lhs.val.sext(width), rhs.val.sext(width), APInt::Rounding::DOWN));
225 SlowMPInt
detail::mod(
const SlowMPInt &lhs,
const SlowMPInt &rhs) {
226 assert(rhs >= 1 &&
"mod is only supported for positive divisors!");
227 return lhs % rhs < 0 ? lhs % rhs + rhs : lhs % rhs;
230 SlowMPInt
detail::gcd(
const SlowMPInt &a,
const SlowMPInt &b) {
231 assert(a >= 0 && b >= 0 &&
"operands must be non-negative!");
233 return SlowMPInt(llvm::APIntOps::GreatestCommonDivisor(a.val.sext(width),
238 SlowMPInt
detail::lcm(
const SlowMPInt &a,
const SlowMPInt &b) {
239 SlowMPInt x =
abs(a);
240 SlowMPInt y =
abs(b);
241 return (x * y) /
gcd(x, y);
246 unsigned width =
std::max(val.getBitWidth(), o.val.getBitWidth());
247 return SlowMPInt(val.sext(width).srem(o.val.sext(width)));
251 if (val.isMinSignedValue()) {
253 APInt ret = val.sext(2 * val.getBitWidth());
static Value max(ImplicitLocOpBuilder &builder, Value value, Value bound)
static unsigned getMaxWidth(const APInt &a, const APInt &b)
APInt runOpWithExpandOnOverflow(const APInt &a, const APInt &b, llvm::function_ref< APInt(const APInt &, const APInt &, bool &overflow)> op)
Bring a and b to have the same width and then call op(a, b, overflow).
A simple class providing multi-precision arithmetic.
SlowMPInt operator+(const SlowMPInt &o) const
bool operator<=(const SlowMPInt &o) const
SlowMPInt & operator-=(const SlowMPInt &o)
SlowMPInt & operator/=(const SlowMPInt &o)
bool operator==(const SlowMPInt &o) const
SlowMPInt operator/(const SlowMPInt &o) const
SlowMPInt & operator+=(const SlowMPInt &o)
bool operator>(const SlowMPInt &o) const
SlowMPInt operator*(const SlowMPInt &o) const
SlowMPInt operator-() const
SlowMPInt operator%(const SlowMPInt &o) const
This operation cannot overflow.
bool operator>=(const SlowMPInt &o) const
SlowMPInt & operator=(int64_t val)
void print(llvm::raw_ostream &os) const
bool operator!=(const SlowMPInt &o) const
SlowMPInt & operator%=(const SlowMPInt &o)
bool operator<(const SlowMPInt &o) const
SlowMPInt & operator*=(const SlowMPInt &o)
bool operator==(const SlowMPInt &a, int64_t b)
SlowMPInt operator/(const SlowMPInt &a, int64_t b)
SlowMPInt gcd(const SlowMPInt &a, const SlowMPInt &b)
llvm::hash_code hash_value(const SlowMPInt &x)
SlowMPInt & operator*=(SlowMPInt &a, int64_t b)
SlowMPInt & operator+=(SlowMPInt &a, int64_t b)
SlowMPInt & operator%=(SlowMPInt &a, int64_t b)
bool operator<(const SlowMPInt &a, int64_t b)
SlowMPInt abs(const SlowMPInt &x)
Redeclarations of friend declarations above to make it discoverable by lookups.
SlowMPInt mod(const SlowMPInt &lhs, const SlowMPInt &rhs)
Returns the remainder of dividing LHS by RHS.
SlowMPInt operator+(const SlowMPInt &a, int64_t b)
SlowMPInt operator*(const SlowMPInt &a, int64_t b)
SlowMPInt lcm(const SlowMPInt &a, const SlowMPInt &b)
Returns the least common multiple of 'a' and 'b'.
bool operator>(const SlowMPInt &a, int64_t b)
bool operator>=(const SlowMPInt &a, int64_t b)
SlowMPInt floorDiv(const SlowMPInt &lhs, const SlowMPInt &rhs)
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const SlowMPInt &x)
SlowMPInt operator%(const SlowMPInt &a, int64_t b)
SlowMPInt operator-(const SlowMPInt &a, int64_t b)
bool operator!=(const SlowMPInt &a, int64_t b)
SlowMPInt ceilDiv(const SlowMPInt &lhs, const SlowMPInt &rhs)
bool operator<=(const SlowMPInt &a, int64_t b)
SlowMPInt & operator-=(SlowMPInt &a, int64_t b)
SlowMPInt & operator/=(SlowMPInt &a, int64_t b)
Include the generated interface declarations.