18 upper = is_bool_type(
t) ? 1 : compute_upper_bound(
t) - 1;
23 return is_signedbv_type(
t) || is_unsignedbv_type(
t) || is_bool_type(
t) ||
51 auto is_signed = is_signedbv_type(
t);
100 auto mod = compute_upper_bound(
t);
102 auto lhs = (b - a) % mod;
105 auto rhs = (c - a) % mod;
225 if (
t.is_included(s))
283 std::sort(r.begin(), r.end(), [](
auto a,
auto b) {
289 return *a.lower < *b.lower;
292 for (
unsigned i = 0; i < r.size(); ++i)
302 for (
unsigned i = 0; i < r.size(); ++i)
367 std::vector<wrapped_interval> r;
392 static std::vector<wrapped_interval>
397 std::vector<wrapped_interval> result;
429 result.push_back(a_d);
430 result.push_back(c_b);
434 if (
t.contains(a) &&
t.contains(b))
452 result.push_back(a_d);
462 result.push_back(c_b);
478 if (
t.is_included(s))
528 assert(f1.
t == f2.
t);
539 assert(!f1_to_f2.is_bottom());
542 if (*f1_to_f2.lower == *f1.
lower && *f1_to_f2.upper == *f2.
upper)
545 double_upper.
lower = *f1_to_f2.lower;
549 return over_join(f1_to_f2, double_upper);
553 if (*f1_to_f2.lower == *f2.
lower && *f1_to_f2.upper == *f1.
upper)
560 return over_join(f1_to_f2, double_lower);
600 assert(*result.
lower >= 0);
601 assert(*result.
upper >= 0);
624 if (*result.
lower < 0)
625 *result.
lower += mod;
626 if (*result.
upper < 0)
627 *result.
upper += mod;
628 assert(*result.
lower >= 0);
629 assert(*result.
upper >= 0);
655 std::vector<wrapped_interval>
ssplit()
const
657 std::vector<wrapped_interval> r;
704 std::vector<wrapped_interval>
nsplit()
const
706 std::vector<wrapped_interval> r;
749 std::vector<wrapped_interval> r;
751 for (
const auto &w : u.
nsplit())
753 for (
const auto &s : w.ssplit())
763 return (b >> (
t->get_width() - 1)) == 1;
776 if (is_bool_type(new_type))
792 return old.
trunc(new_type);
794 if (is_signedbv_type(old.
t))
802 std::vector<wrapped_interval> parts;
804 for (
auto &interval :
ssplit())
807 result.
lower = interval.lower;
808 result.
upper = interval.upper;
809 parts.push_back(result);
992 minimum =
std::min(minimum, local_min);
993 maximum =
std::max(maximum, local_max);
995 return std::make_pair(minimum, maximum);
1005 result.
set_lower(lhs_bounds.second < rhs_bounds.first ? 1 : 0);
1006 result.
set_upper(lhs_bounds.first >= rhs_bounds.second ? 0 : 1);
1018 result.
set_lower(lhs_bounds.second <= rhs_bounds.first ? 1 : 0);
1019 result.
set_upper(lhs_bounds.first > rhs_bounds.second ? 0 : 1);
1038 std::vector<wrapped_interval> parts;
1040 auto compute_outer_region = [
this, &
cast](
bool bit) {
1048 for (
auto &interval :
nsplit())
1057 parts.push_back(result);
1066 auto k =
cast->get_width();
1067 assert(k <= t->get_width());
1079 ((*
lower >> k) + 1 % 2) == (*
upper >> k) % 2 &&
1088 static std::vector<wrapped_interval>
1098 auto &a = *lhs.
lower;
1099 auto &b = *lhs.
upper;
1100 auto &c = *rhs.
lower;
1101 auto &d = *rhs.
upper;
1103 if (b * d - a * c < up)
1105 w_u.
lower = (a * c) % up;
1106 w_u.
upper = (b * d) % up;
1112 (b * d - a * c < up))
1114 w_s.
lower = a * c % up;
1115 w_s.
upper = b * d % up;
1120 (b * c - a * d < up))
1122 w_s.
lower = a * d % up;
1123 w_s.
upper = b * c % up;
1128 (a * d - b * c < up))
1130 w_s.
lower = b * c % up;
1131 w_s.
upper = a * d % up;
1141 std::vector<wrapped_interval> r;
1142 for (
auto &u :
cut(lhs))
1143 for (
auto &v :
cut(rhs))
1160 std::vector<wrapped_interval> r;
1166 for (
auto &u : s.
ssplit())
1167 for (
auto &v :
t.ssplit())
1173 r.push_back(u - ((u / v_non_zero) * v_non_zero));
1177 r.push_back(-
amb(v));
1179 r.push_back(
amb(v));
1188 std::vector<wrapped_interval> r;
1193 if (!is_signedbv_type(lhs.
t))
1195 for (
const auto &u : lhs.
ssplit())
1196 for (
const auto &v : rhs.
ssplit())
1200 temp.
lower = *u.lower / *non_zero.upper;
1201 temp.
upper = *u.upper / *non_zero.lower;
1207 for (
const auto &u :
cut(lhs))
1208 for (
const auto &v :
cut(rhs))
1216 if (!msb_a && !msb_c)
1218 temp.
set_lower(u.get_lower() / non_zero.get_upper());
1219 temp.
set_upper(u.get_upper() / non_zero.get_lower());
1221 else if (msb_a && msb_c)
1223 temp.
set_lower(u.get_upper() / non_zero.get_lower());
1224 temp.
set_upper(u.get_lower() / non_zero.get_upper());
1226 else if (!msb_a && msb_c)
1228 temp.
set_lower(u.get_upper() / non_zero.get_upper());
1229 temp.
set_upper(u.get_lower() / non_zero.get_lower());
1231 else if (msb_a && !msb_c)
1233 temp.
set_lower(u.get_lower() / non_zero.get_lower());
1234 temp.
set_upper(u.get_upper() / non_zero.get_upper());
1248 typedef std::function<uint64_t(uint64_t, uint64_t, uint64_t, uint64_t)>
1256 [&width](uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
1258 m = compute_m(width);
1263 temp = (a | m) & -m;
1270 else if (a & ~c & m)
1272 temp = (c | m) & -m;
1284 [&width](uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
1286 m = compute_m(width);
1288 assert(m == 0x80000000);
1293 temp = (b - m) | (m - 1);
1299 temp = (d - m) | (m - 1);
1310 return warren_approximation(lhs, rhs, min_or, max_or);
1317 const auto min_and =
1318 [&width](uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
1321 m = compute_m(width);
1326 temp = (a | m) & -m;
1332 temp = (c | m) & -m;
1343 const auto max_and =
1344 [&width](uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
1347 m = compute_m(width);
1352 temp = (b & ~m) | (m - 1);
1359 else if (~b & d & m)
1361 temp = (d & ~m) | (m - 1);
1372 return warren_approximation(lhs, rhs, min_and, max_and);
1379 const auto min_xor =
1380 [&width](uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
1382 m = compute_m(width);
1387 temp = (a | m) & -m;
1393 else if (a & ~c & m)
1395 temp = (c | m) & -m;
1405 const auto max_xor =
1406 [&width](uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
1408 m = compute_m(width);
1413 temp = (b - m) | (m - 1);
1420 temp = (d - m) | (m - 1);
1431 return warren_approximation(lhs, rhs, min_xor, max_xor);
1454 if (!
cond.contains(0))
1457 if (
cond.singleton())
1460 return over_join(true_value, false_value);
1469 if (is_pointer_type(
t))
1476 static uint64_t compute_m(
unsigned width)
1478 assert(width - 1 < 64);
1479 uint64_t m = (uint64_t)1 << (width - 1);
1481 assert(m == 0x80000000);
1496 std::vector<wrapped_interval> r;
1497 for (
auto &u : lhs.
ssplit())
1498 for (
auto &v : rhs.
ssplit())
1500 auto u_lower = (*u.lower).to_uint64();
1501 auto u_upper = (*u.upper).to_uint64();
1503 auto v_lower = (*v.lower).to_uint64();
1504 auto v_upper = (*v.upper).to_uint64();
1507 temp.lower =
min(u_lower, u_upper, v_lower, v_upper);
1508 temp.upper =
max(u_lower, u_upper, v_lower, v_upper);
static BigInt power2(unsigned n)
Definition bigint.hh:310
bool is_zero() const
Definition bigint.hh:218
bool is_negative() const
Definition bigint.hh:226
static BigInt power2m1(unsigned n)
Definition bigint.hh:318
uint64_t to_uint64() const
Definition bigint.cpp:659
T get_lower() const
Definition interval_template.h:42
void set_lower(const T &b)
Definition interval_template.h:75
void set_upper(const T &b)
Definition interval_template.h:71
bool is_bottom() const
Definition interval_template.h:117
std::optional< BigInt > upper
Definition interval_template.h:39
BigInt get_upper() const
Definition interval_template.h:47
bool singleton() const
There is only one value that satisfies.
Definition interval_template.h:128
interval_templatet()=default
std::optional< BigInt > lower
Definition interval_template.h:39
unsigned int get_width() const
Fetch bit width of this type.
Definition irep2_type.cpp:352
Definition wrapped_interval.h:6
friend wrapped_interval operator-(const wrapped_interval &lhs)
Definition wrapped_interval.h:517
static bool is_representable(const type2tc &t)
Definition wrapped_interval.h:21
static wrapped_interval south_pole(const type2tc &t)
Definition wrapped_interval.h:645
wrapped_interval trunc(const type2tc &cast) const
Definition wrapped_interval.h:1063
bool most_significant_bit(const BigInt &b) const
Definition wrapped_interval.h:761
std::vector< wrapped_interval > ssplit() const
Definition wrapped_interval.h:655
bool is_included(const wrapped_interval &rhs) const
Definition wrapped_interval.h:209
wrapped_interval logical_right_shift(unsigned k) const
Definition wrapped_interval.h:849
static wrapped_interval logical_right_shift(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:869
BigInt get_min() const
Definition wrapped_interval.h:170
static wrapped_interval left_shift(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:837
BigInt get_max() const
Definition wrapped_interval.h:176
static wrapped_interval under_meet(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:387
bool is_equal(const wrapped_interval &rhs) const
Definition wrapped_interval.h:204
wrapped_interval sign_extension(const type2tc &cast) const
Definition wrapped_interval.h:1036
static wrapped_interval less_than_equal(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1012
static wrapped_interval difference(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:699
bool contains(const BigInt &e) const override
Definition wrapped_interval.h:196
void make_le_than(const wrapped_interval &rhs)
Definition wrapped_interval.h:124
friend wrapped_interval operator-(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:608
void make_ge_than(const BigInt &v) override
Definition wrapped_interval.h:143
static BigInt trunc(const BigInt &b, unsigned k)
Definition wrapped_interval.h:766
static std::vector< wrapped_interval > intersection(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:393
static wrapped_interval over_join(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:312
friend wrapped_interval operator%(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:1158
friend wrapped_interval operator^(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1376
static wrapped_interval over_meet(const wrapped_interval &s, const wrapped_interval &t)
Over meet.
Definition wrapped_interval.h:471
std::vector< wrapped_interval > nsplit() const
Definition wrapped_interval.h:704
wrapped_interval(const type2tc &t)
Definition wrapped_interval.h:12
BigInt cardinality() const
Definition wrapped_interval.h:183
wrapped_interval zero_extension(const type2tc &cast) const
Definition wrapped_interval.h:800
static std::vector< wrapped_interval > multiply_us(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1089
static wrapped_interval less_than(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:999
friend wrapped_interval operator*(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1138
static wrapped_interval cast(const wrapped_interval &old, const type2tc &new_type)
Definition wrapped_interval.h:773
bool empty() const override
Checks whether there are values that satisfy the the interval.
Definition wrapped_interval.h:65
wrapped_interval left_shift(unsigned k) const
Definition wrapped_interval.h:815
void approx_union_with(const interval_templatet< BigInt > &i) override
Definition wrapped_interval.h:375
std::pair< BigInt, BigInt > get_interval_bounds() const
Computes the minimum and maximum value inside the interval.
Definition wrapped_interval.h:982
static wrapped_interval invert_bool(const wrapped_interval &i)
Definition wrapped_interval.h:938
bool is_top() const override
Definition wrapped_interval.h:70
const BigInt & get_upper_bound() const
Definition wrapped_interval.h:1442
BigInt upper_bound
Definition wrapped_interval.h:1464
static wrapped_interval north_pole(const type2tc &t)
Definition wrapped_interval.h:635
static std::vector< wrapped_interval > cut(const wrapped_interval &u)
Definition wrapped_interval.h:747
void make_le_than(const BigInt &v) override
Definition wrapped_interval.h:112
static wrapped_interval gap(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:249
static wrapped_interval bitnot(const wrapped_interval &w)
Definition wrapped_interval.h:1434
wrapped_interval arithmetic_right_shift(unsigned k) const
Definition wrapped_interval.h:881
static wrapped_interval ternary_if(const wrapped_interval &cond, const wrapped_interval &true_value, const wrapped_interval &false_value)
Definition wrapped_interval.h:1449
static wrapped_interval extrapolate_to(const wrapped_interval &f1, const wrapped_interval &f2)
Definition wrapped_interval.h:526
static wrapped_interval extend(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:221
friend wrapped_interval operator&(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1314
static wrapped_interval bigger(const wrapped_interval &s, const wrapped_interval &t)
Definition wrapped_interval.h:265
static wrapped_interval amb(const wrapped_interval &rhs)
Definition wrapped_interval.h:1149
static wrapped_interval equality(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:916
wrapped_interval()
Definition wrapped_interval.h:8
BigInt get(bool is_upper) const override
Definition wrapped_interval.h:49
static wrapped_interval complement(const wrapped_interval &w)
Definition wrapped_interval.h:75
static wrapped_interval not_equal(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:963
void make_ge_than(const wrapped_interval &rhs)
Definition wrapped_interval.h:151
static bool wrapped_le(const BigInt &b, const BigInt &a, const BigInt &c, const type2tc &t)
b <=_a c iff b -_w a <= c -_w a
Definition wrapped_interval.h:94
static wrapped_interval greater_than_equal(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1025
friend wrapped_interval operator+(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:584
type2tc t
Definition wrapped_interval.h:1447
bool bottom
Definition wrapped_interval.h:64
BigInt convert_to_wrap(const BigInt &b) const
Definition wrapped_interval.h:27
static wrapped_interval over_join(std::vector< wrapped_interval > &r)
Over union.
Definition wrapped_interval.h:271
static wrapped_interval arithmetic_right_shift(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:901
std::function< uint64_t(uint64_t, uint64_t, uint64_t, uint64_t)> warren_approximation_function
Definition wrapped_interval.h:1249
void set(bool is_upper, const BigInt &b) override
Definition wrapped_interval.h:39
friend wrapped_interval operator/(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1186
static wrapped_interval greater_than(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1031
friend wrapped_interval operator|(const wrapped_interval &lhs, const wrapped_interval &rhs)
Definition wrapped_interval.h:1252
configt config
Definition config.cpp:8
pthread_cond_t cond
Definition cuda.h:50
@ zero
Success iff the returned integer is zero (e.g. pthread_mutex_lock).
Definition fallible_calls.h:26
irep_container< type2t > type2tc
Definition irep2.h:430
#define log_error(fmt,...)
Definition message.h:83
const T & max(const T &left, const T &right)
Definition min_max.h:10
const T & min(const T &left, const T &right)
Definition min_max.h:19
void * value
Definition solidity_mapping.c:2
void abort(void)
Definition stdlib.c:77
TOML_PURE_INLINE_GETTER constexpr const T & min(const T &a, const T &b) noexcept
Definition toml.hpp:2491