51 #define CASE_MISCELLANEOUS \ 53 case case_label_expr_K: \ 56 case target_mem_ref_K: \ 57 case target_mem_ref461_K: \ 62 case identifier_node_K: \ 64 case statement_list_K: \ 90 return new Range(*
this);
111 else if((lb ==
Min) && (ub ==
Max))
129 const bool lbgt = lb > maxS;
130 const bool ubgt = ub > maxS;
131 const bool lblt = lb < minS;
132 const bool ublt = ub < minS;
147 else if(lblt && ublt)
161 else if(!lblt && ubgt)
176 else if(lblt && !ubgt)
191 else if(!lblt && !ubgt)
214 else if(lb ==
Min && ub ==
Max)
228 else if(lb >= minS && lb < 0)
233 else if(lb >= 0 && lb <= maxS)
258 else if(ub >= minS && ub < 0)
263 else if(ub >= 0 && ub <= maxS)
285 const bool lbgt = lb > maxS;
286 const bool ubgt = ub > maxS;
287 const bool lblt = lb < minS;
288 const bool ublt = ub < minS;
294 else if(lbgt && ubgt)
299 else if(lblt && ublt)
304 else if(!lblt && ubgt)
319 else if(lblt && !ubgt)
334 else if(!lblt && !ubgt)
367 THROW_ASSERT(bv.size() <= bitwidth,
"BitValues size not appropriate");
368 auto bitstring_to_int = [&](
const std::deque<bit_lattice>& bv_in) {
370 auto bv_it = bv_in.crbegin();
371 const auto bv_end = bv_in.crend();
372 for(
size_t i = 0; bv_it != bv_end; ++i, ++bv_it)
385 auto manip = [&](
const std::deque<bit_lattice>& bv_in) {
386 if(bv_in.size() < bitwidth)
393 const auto max = [&]() {
394 std::deque<bit_lattice> bv_out;
398 for(
auto it = ++(bv.begin()); it != bv.end(); ++it)
402 return manip(bv_out);
404 const auto min = [&]() {
405 std::deque<bit_lattice> bv_out;
409 for(
auto it = ++(bv.begin()); it != bv.end(); ++it)
413 return manip(bv_out);
435 if(shorter.size() < longer.size())
440 std::deque<bit_lattice> range_bv;
441 auto s_it = shorter.cbegin();
442 auto l_it = longer.cbegin();
443 const auto s_end = shorter.cend();
444 const auto l_end = longer.cend();
445 for(; s_it != s_end && l_it != l_end; s_it++, l_it++)
449 range_bv.push_back(*s_it);
456 while(range_bv.size() < longer.size())
480 return RangeRef(this->
clone());
516 return u > maxS ? maxS :
u;
528 return l < minS ? minS :
l;
574 return 1 + uLimit - lLimit;
609 return type == other->type;
614 return this->
bw == other->bw &&
isSameType(other) && (
l == other->l) && (
u == other->u);
641 #define RETURN_EMPTY_ON_EMPTY(b) \ 642 if(this->isEmpty() || other->isEmpty()) \ 644 return RangeRef(new Range(Empty, b)); \ 646 #define RETURN_UNKNOWN_ON_UNKNOWN(b) \ 647 if(this->isUnknown() || other->isUnknown()) \ 649 return RangeRef(new Range(Unknown, b)); \ 657 if(this->
isFullSet() || other->isFullSet())
661 if(
isAnti() && other->isConstant())
663 auto ol = other->getLower();
670 if(this->
isAnti() || other->isAnti())
674 if(other->isConstant())
676 auto ol = other->getLower();
694 if(res->getSpan() <=
getSpan() || res->getSpan() <= other->getSpan())
706 if(this->
isFullSet() || other->isFullSet())
710 if(
isAnti() && other->isConstant())
712 auto ol = other->getLower();
715 return RangeRef(this->
clone());
723 if(this->
isAnti() || other->isAnti())
727 if(other->isConstant())
729 auto ol = other->getLower();
732 return RangeRef(this->
clone());
763 if(res->getSpan() <=
getSpan() || res->getSpan() <= other->getSpan())
775 if(this->
isFullSet() || other->isFullSet())
779 if(
isAnti() && other->isConstant())
781 auto ol = other->getLower();
788 if(this->
isAnti() || other->isAnti())
792 if(other->isConstant())
794 auto ol = other->getLower();
812 if(res->getSpan() <=
getSpan() || res->getSpan() <= other->getSpan())
824 if(this->
isFullSet() || other->isFullSet())
828 if(this->
isAnti() && other->isConstant())
830 auto ol = other->getLower();
838 if(this->
isAnti() || other->isAnti())
842 if(other->isConstant())
844 auto ol = other->getLower();
870 auto lower = (
l - ol).extOrTrunc(
bw,
true);
871 auto upper = (
u - ol).extOrTrunc(
bw,
true);
876 return RangeRef(
new Range(
Anti,
bw, upper + 1, lower - 1));
882 if(res->getSpan() <
getSpan() || res->getSpan() < other->getSpan())
894 if(this->
isFullSet() || other->isFullSet())
898 if(this->
isAnti() && other->isConstant())
900 auto ol = other->getLower();
903 return RangeRef(this->
clone());
911 if(this->
isAnti() || other->isAnti())
915 if(other->isConstant())
917 auto ol = other->getLower();
947 if(res->getSpan() <
getSpan() || res->getSpan() < other->getSpan())
959 if(this->
isFullSet() || other->isFullSet())
963 if(this->
isAnti() && other->isConstant())
965 auto ol = other->getLower();
968 return RangeRef(this->
clone());
976 if(this->
isAnti() || other->isAnti())
980 if(other->isConstant())
982 auto ol = other->getLower();
1006 if(res->getSpan() <
getSpan() || res->getSpan() < other->getSpan())
1018 if(this->
isFullSet() || other->isFullSet() || this->
isAnti() || other->isAnti())
1032 auto Other_min = other->getUnsignedMin();
1033 auto Other_max = other->getUnsignedMax();
1035 const auto Result_zext =
Range(
Regular, static_cast<bw_t>(
bw * 2), this_min * Other_min, this_max * Other_max);
1036 const auto UR = Result_zext.truncate(
bw);
1046 Other_min = other->getSignedMin();
1047 Other_max = other->getSignedMax();
1050 std::minmax({this_min * Other_min, this_min * Other_max, this_max * Other_min, this_max * Other_max});
1051 const auto Result_sext =
Range(
Regular, static_cast<bw_t>(
bw * 2), res.first, res.second);
1052 const auto SR = Result_sext.truncate(
bw);
1054 return UR->getSpan() < SR->getSpan() ? UR : SR;
1069 auto c = other->getUnsignedMin();
1070 auto d = other->getUnsignedMax();
1073 if((c == 0) && (d == 0))
1085 #define DIV_HELPER(x, y) \ 1087 (((y) < 0) ? Min : (((y) == 0) ? 0 : Max)) : \ 1088 (((y) == Max) ? 0 : \ 1089 (((x) == Min) ? (((y) < 0) ? Max : (((y) == 0) ? 0 : Min)) : (((y) == Min) ? 0 : ((x) / (y))))) 1104 bool is_zero_in =
false;
1107 auto antiRange = other->getAnti();
1109 d1 = antiRange->getLower() - 1;
1118 c2 = antiRange->getUpper() + 1;
1131 c1 = other->getLower();
1132 d1 = other->getUpper();
1134 if((c1 == 0) && (d1 == 0))
1138 is_zero_in = (c1 < 0) && (d1 > 0);
1146 c2 = other->getLower();
1152 d2 = other->getUpper();
1158 auto n_iters = (is_zero_in || other->isAnti()) ? 8
u : 4
u;
1160 APInt candidates[8];
1173 auto res = std::minmax_element(candidates, candidates + n_iters);
1174 return RangeRef(
new Range(
Regular,
bw, *res.first, *res.second));
1182 if(this->
isAnti() || other->isAnti())
1186 if(other->isConstant())
1188 if(other->getLower() == 0)
1192 else if(other->getUnsignedMin() == 1)
1200 APInt c = other->getUnsignedMin();
1201 const APInt& d = other->getUnsignedMax();
1204 if((c == 0) && (d == 0))
1213 APInt candidates[8];
1215 candidates[0] = a < c ? a : 0;
1216 candidates[1] = a < d ? a : 0;
1217 candidates[2] = b < c ? b : 0;
1218 candidates[3] = b < d ? b : 0;
1219 candidates[4] = a < c ? a : c - 1;
1220 candidates[5] = a < d ? a : d - 1;
1221 candidates[6] = b < c ? b : c - 1;
1222 candidates[7] = b < d ? b : d - 1;
1225 auto res = std::minmax_element(candidates, candidates + 8);
1226 return RangeRef(
new Range(
Regular,
bw, *res.first, *res.second));
1241 const auto& c = other->getLower();
1242 const auto& d = other->getUpper();
1245 if(c <= 0 && d >= 0)
1250 const auto dmin =
std::min(c.abs(), d.abs());
1251 const auto dmax =
std::max(c.abs(), d.abs());
1252 const auto abs_min =
std::min(a.abs(), b.abs());
1253 const auto abs_max =
std::max(a.abs(), b.abs());
1254 if((abs_min < dmin && dmin < abs_max) || (abs_min < dmax && dmax < abs_max))
1256 return RangeRef(
new Range(
Regular,
bw, a >= 0 ? 0 : (a.abs() < dmax ? a : -(dmax - 1)),
1257 b <= 0 ? 0 : (b.abs() < dmax ? b : (dmax - 1))));
1259 else if(abs_max < dmin)
1261 return RangeRef(this->
clone());
1263 return RangeRef(
new Range(
Regular,
bw, a < 0 ? -(dmax - 1) : 0, b > 0 ? (dmax - 1) : 0));
1271 if(this->
isFullSet() || other->isFullSet() || this->
isAnti() || other->isAnti())
1275 if(this->
isConstant() && other->isConstant())
1278 .extOrTrunc(
bw,
true);
1284 const auto fix = other->zextOrTrunc(static_cast<bw_t>(
ceil_log2(
bw)));
1285 const auto c = fix->getUnsignedMin();
1286 const auto d = fix->getUnsignedMax();
1298 if(d > a.leadingOnes(
bw))
1306 if(d >
std::min(a.leadingOnes(
bw), b.leadingZeros(
bw)))
1312 if(d > b.leadingZeros(
bw))
1324 if(this->
isAnti() || other->isAnti())
1329 const auto fix = other->zextOrTrunc(static_cast<bw_t>(
ceil_log2(
bw)));
1330 const auto c = fix->getUnsignedMin();
1331 const auto d = fix->getUnsignedMax();
1337 const auto min = a >= 0 ? a >> d : a >> c;
1338 const auto max = b >= 0 ? b >> c : b >> d;
1362 for(
auto i = 0; i <
bw; ++i)
1366 temp = (a | m) & nm;
1375 temp = (c | m) & nm;
1393 for(
auto i = 0; i <
bw; ++i)
1397 temp = (b - m) | mm;
1403 temp = (d - m) | mm;
1418 auto abcd = ((a >= 0) << 3) | ((b >= 0) << 2) | ((c >= 0) << 1) | (d >= 0);
1420 APInt res_l = 0, res_u = 0;
1427 res_l = minOR(bw, a, b, c, d);
1428 res_u = maxOR(bw, a, b, c, d);
1431 return std::make_pair(a, -1);
1433 return std::make_pair(c, -1);
1436 res_u = maxOR(bw, 0, b, 0, d);
1439 res_l = minOR(bw, a, -1, c, d);
1440 res_u = maxOR(bw, 0, b, c, d);
1443 res_l = minOR(bw, a, b, c, -1);
1444 res_u = maxOR(bw, a, b, 0, d);
1449 return std::make_pair(res_l, res_u);
1457 for(
auto i = 0; i <
bw; ++i)
1461 temp = (a | m) & nm;
1467 temp = (c | m) & nm;
1485 for(
auto i = 0; i <
bw; ++i)
1489 temp = (b & ~m) | mm;
1498 temp = (d & ~m) | mm;
1513 auto abcd = ((a >= 0) << 3) | ((b >= 0) << 2) | ((c >= 0) << 1) | (d >= 0);
1515 APInt res_l = 0, res_u = 0;
1522 res_l = minAND(bw, a, b, c, d);
1523 res_u = maxAND(bw, a, b, c, d);
1526 res_l = minAND(bw, a, b, c, -1);
1527 res_u = maxAND(bw, a, b, 0, d);
1530 res_l = minAND(bw, a, -1, c, d);
1531 res_u = maxAND(bw, 0, b, c, d);
1534 res_l = minAND(bw, a, -1, c, -1);
1538 return std::make_pair(0, d);
1540 return std::make_pair(0, b);
1544 return std::make_pair(res_l, res_u);
1552 for(
auto i = 0; i <
bw; ++i)
1556 temp = (a | m) & nm;
1564 temp = (c | m) & nm;
1581 for(
auto i = 0; i <
bw; ++i)
1585 temp = (b - m) | mm;
1592 temp = (d - m) | mm;
1607 return std::make_pair(minXOR(bw, a, b, c, d), maxXOR(bw, a, b, c, d));
1619 return RangeRef(other->clone());
1621 if(other->isConstant() && other->getSignedMax() == 0)
1623 return RangeRef(this->
clone());
1628 const auto& c = other->isAnti() ?
Min : other->getLower();
1629 const auto& d = other->isAnti() ?
Max : other->getUpper();
1631 const auto res =
OR(
bw, a, b, c, d);
1642 return RangeRef(other->clone());
1644 if(other->isConstant() && other->getSignedMax() == -1)
1646 return RangeRef(this->
clone());
1651 const auto& c = other->isAnti() ?
Min : other->getLower();
1652 const auto& d = other->isAnti() ?
Max : other->getUpper();
1654 const auto res =
AND(
bw, a, b, c, d);
1666 const auto& c = other->isAnti() ?
Min : other->getLower();
1667 const auto& d = other->isAnti() ?
Max : other->getUpper();
1669 if(a >= 0 && b >= 0 && c >= 0 && d >= 0)
1671 const auto res = uXOR(
bw, a, b, c, d);
1674 else if(a == -1 && b == -1 && c >= 0 && d >= 0)
1676 return this->
sub(other);
1678 else if(c == -1 && d == -1 && a >= 0 && b >= 0)
1680 return other->sub(RangeRef(this->
clone()));
1693 const auto min = ~this->u;
1694 const auto max = ~this->l;
1701 THROW_ASSERT(!other->isReal(),
"Real range is a storage class only");
1704 if(this->
isAnti() && other->isAnti())
1708 if(!this->
isAnti() && !other->isAnti())
1710 if((
l ==
Min) || (
u ==
Max) || (other->l ==
Min) || (other->u ==
Max))
1716 bool areTheyDifferent = !((
l ==
u) && this->
isSameRange(other));
1718 if(areTheyEqual && areTheyDifferent)
1722 if(areTheyEqual && !areTheyDifferent)
1726 if(!areTheyEqual && areTheyDifferent)
1737 THROW_ASSERT(!other->isReal(),
"Real range is a storage class only");
1740 if(this->
isAnti() && other->isAnti())
1744 if(!this->
isAnti() && !other->isAnti())
1746 if((
l ==
Min) || (
u ==
Max) || (other->l ==
Min) || (other->u ==
Max))
1752 bool areTheyDifferent = !((
l ==
u) && this->
isSameRange(other));
1753 if(areTheyEqual && areTheyDifferent)
1757 if(areTheyEqual && !areTheyDifferent)
1761 if(!areTheyEqual && areTheyDifferent)
1775 if(
isAnti() || other->isAnti())
1782 const auto c = other->getUnsignedMin();
1783 const auto d = other->getUnsignedMax();
1801 if(
isAnti() || other->isAnti())
1808 const auto c = other->getUnsignedMin();
1809 const auto d = other->getUnsignedMax();
1827 if(
isAnti() || other->isAnti())
1834 const auto c = other->getUnsignedMin();
1835 const auto d = other->getUnsignedMax();
1853 if(
isAnti() || other->isAnti())
1860 const auto c = other->getUnsignedMin();
1861 const auto d = other->getUnsignedMax();
1879 if(
isAnti() || other->isAnti())
1886 const auto c = other->getSignedMin();
1887 const auto d = other->getSignedMax();
1905 if(
isAnti() || other->isAnti())
1912 const auto c = other->getSignedMin();
1913 const auto d = other->getSignedMax();
1931 if(
isAnti() || other->isAnti())
1938 const auto c = other->getSignedMin();
1939 const auto d = other->getSignedMax();
1957 if(
isAnti() || other->isAnti())
1964 const auto c = other->getSignedMin();
1965 const auto d = other->getSignedMax();
1983 if(
isAnti() || other->isAnti())
1988 const auto thisMin = this->
Slt(other, 1);
1989 if(thisMin->isConstant())
1991 return thisMin->getUnsignedMin() ? RangeRef(this->
clone()) : RangeRef(other->clone());
2003 if(
isAnti() || other->isAnti())
2008 const auto thisMax = this->
Sgt(other, 1);
2009 if(thisMax->isConstant())
2011 return thisMax->getUnsignedMin() ? RangeRef(this->
clone()) : RangeRef(other->clone());
2023 if(
isAnti() || other->isAnti())
2028 const auto thisMin = this->
Ult(other, 1);
2029 if(thisMin->isConstant())
2031 return thisMin->getUnsignedMin() ? RangeRef(this->
clone()) : RangeRef(other->clone());
2043 if(
isAnti() || other->isAnti())
2048 const auto thisMax = this->
Ugt(other, 1);
2049 if(thisMax->isConstant())
2051 return thisMax->getUnsignedMin() ? RangeRef(this->
clone()) : RangeRef(other->clone());
2062 return RangeRef(this->
clone());
2092 return RangeRef(
new Range(
Anti,
bw, smin + 1, -smax - 1));
2100 return RangeRef(
new Range(
Anti,
bw, smin + 1, -1));
2105 return RangeRef(this->
clone());
2113 return RangeRef(this->
clone());
2138 return RangeRef(this->
clone());
2147 const auto stmin = a.extOrTrunc(bitwidth,
true);
2148 const auto stmax = b.extOrTrunc(bitwidth,
true);
2158 return RangeRef(
new Range(
Anti, bitwidth, stmax + 1, (stmin < 0 ? stmin : 0) - 1));
2166 return RangeRef(
new Range(
Anti, bitwidth, stmax + 1, stmin - 1));
2174 return RangeRef(
new Range(
Regular, bitwidth, stmax, stmin));
2176 return RangeRef(
new Range(
Anti, bitwidth, stmax + 1, stmin - 1));
2178 return RangeRef(
new Range(
Regular, bitwidth, stmin, stmax));
2200 const auto res = std::minmax({this_min.extOrTrunc(bitwidth,
true), this_max.extOrTrunc(bitwidth,
true)});
2201 RangeRef sextRes(
new Range(
Regular, bitwidth, res.first, res.second));
2202 if(sextRes->isFullSet())
2244 #ifdef DEBUG_RANGE_OP 2245 PRINT_MSG(
"intersectWith-this: " << *
this << std::endl <<
"intersectWith-other: " << *other);
2251 if(!this->
isAnti() && !other->isAnti())
2262 if(this->
isAnti() && !other->isAnti())
2264 auto antiRange = this->
getAnti();
2265 auto antil = antiRange->getLower();
2266 auto antiu = antiRange->getUpper();
2269 if(other->getUpper() <= antiu)
2273 APInt res_l = other->getLower() > antiu ? other->getLower() : antiu + 1;
2274 APInt res_u = other->getUpper();
2277 if(antiu >= other->getUpper())
2280 APInt res_l = other->getLower();
2281 APInt res_u = other->getUpper() < antil ? other->getUpper() : antil - 1;
2284 if(other->getLower() ==
Min && other->getUpper() ==
Max)
2286 return RangeRef(this->
clone());
2288 if(antil > other->getUpper() || antiu < other->getLower())
2290 return RangeRef(other->clone());
2294 return RangeRef(other->clone());
2296 if(!this->
isAnti() && other->isAnti())
2298 auto antiRange = other->getAnti();
2299 auto antil = antiRange->getLower();
2300 auto antiu = antiRange->getUpper();
2320 return RangeRef(other->clone());
2324 return RangeRef(this->
clone());
2328 return RangeRef(this->
clone());
2331 auto antiRange_a = this->
getAnti();
2332 auto antiRange_b = other->getAnti();
2333 auto antil_a = antiRange_a->getLower();
2334 auto antiu_a = antiRange_a->getUpper();
2335 auto antil_b = antiRange_b->getLower();
2336 auto antiu_b = antiRange_b->getUpper();
2337 if(antil_a > antil_b)
2339 std::swap(antil_a, antil_b);
2340 std::swap(antiu_a, antiu_b);
2342 if(antil_b > (antiu_a + 1))
2344 return RangeRef(
new Range(
Anti,
bw, antil_a, antiu_a));
2346 auto res_l = antil_a;
2347 auto res_u = antiu_a > antiu_b ? antiu_a : antiu_b;
2348 if(res_l ==
Min && res_u ==
Max)
2353 return RangeRef(
new Range(
Anti,
bw, res_l, res_u));
2358 #ifdef DEBUG_RANGE_OP 2359 PRINT_MSG(
"unionWith-this: " << *
this << std::endl <<
"unionWith-other: " << *other);
2364 return RangeRef(other->clone());
2366 if(other->isEmpty() || other->isUnknown())
2368 return RangeRef(this->
clone());
2370 if(!this->
isAnti() && !other->isAnti())
2376 if(this->
isAnti() && !other->isAnti())
2378 auto antiRange = this->
getAnti();
2379 auto antil = antiRange->getLower();
2380 auto antiu = antiRange->getUpper();
2383 if(antil > other->getUpper() || antiu < other->getLower())
2385 return RangeRef(this->
clone());
2387 if(antil > other->getLower() && antiu < other->getUpper())
2391 if(antil >= other->getLower() && antiu > other->getUpper())
2393 return RangeRef(
new Range(
Anti,
bw, other->getUpper() + 1, antiu));
2397 return RangeRef(
new Range(
Anti,
bw, antil, other->getLower() - 1));
2402 if(!this->
isAnti() && other->isAnti())
2404 auto antiRange = other->getAnti();
2405 auto antil = antiRange->getLower();
2406 auto antiu = antiRange->getUpper();
2411 return RangeRef(other->clone());
2429 auto antiRange_a = this->
getAnti();
2430 auto antiRange_b = other->getAnti();
2431 auto antil_a = antiRange_a->getLower();
2432 auto antiu_a = antiRange_a->getUpper();
2435 auto antil_b = antiRange_b->getLower();
2436 auto antiu_b = antiRange_b->getUpper();
2439 if(antil_a > antiu_b || antiu_a < antil_b)
2443 if(antil_a > antil_b && antiu_a < antiu_b)
2445 return RangeRef(this->
clone());
2447 if(antil_b > antil_a && antiu_b < antiu_a)
2449 return RangeRef(this->
clone());
2451 if(antil_a >= antil_b && antiu_b <= antiu_a)
2453 return RangeRef(
new Range(
Anti,
bw, antil_a, antiu_b));
2455 if(antil_b >= antil_a && antiu_a <= antiu_b)
2457 return RangeRef(
new Range(
Anti,
bw, antil_b, antiu_a));
2468 OS <<
"[Unknown," << +
bw <<
"]";
2472 OS <<
"[Empty," << +
bw <<
"]";
2482 OS <<
")" <<
l <<
",";
2502 OS <<
"[" <<
l <<
",";
2518 std::stringstream ss;
2531 const auto bw = Other->bw;
2532 if(Other->isUnknown() || Other->isEmpty())
2534 return RangeRef(Other->clone());
2536 if(Other->isAnti() && pred != eq_expr_K && pred != ne_expr_K && pred != uneq_expr_K)
2541 if(Other->isReal() && pred != eq_expr_K && pred != ne_expr_K && pred != uneq_expr_K)
2566 return RangeRef(Other->clone());
2568 return Other->getAnti();
2571 case bit_and_expr_K:
2572 case bit_ior_expr_K:
2573 case bit_xor_expr_K:
2575 case ceil_div_expr_K:
2576 case ceil_mod_expr_K:
2577 case complex_expr_K:
2578 case compound_expr_K:
2579 case eh_filter_expr_K:
2580 case exact_div_expr_K:
2582 case floor_div_expr_K:
2583 case floor_mod_expr_K:
2584 case goto_subroutine_K:
2587 case lrotate_expr_K:
2595 case mult_highpart_expr_K:
2596 case ordered_expr_K:
2598 case pointer_plus_expr_K:
2599 case postdecrement_expr_K:
2600 case postincrement_expr_K:
2601 case predecrement_expr_K:
2602 case preincrement_expr_K:
2605 case round_div_expr_K:
2606 case round_mod_expr_K:
2607 case rrotate_expr_K:
2610 case trunc_div_expr_K:
2611 case trunc_mod_expr_K:
2612 case truth_and_expr_K:
2613 case truth_andif_expr_K:
2614 case truth_or_expr_K:
2615 case truth_orif_expr_K:
2616 case truth_xor_expr_K:
2617 case try_catch_expr_K:
2620 case unordered_expr_K:
2621 case widen_sum_expr_K:
2622 case widen_mult_expr_K:
2623 case with_size_expr_K:
2624 case vec_lshift_expr_K:
2625 case vec_rshift_expr_K:
2626 case widen_mult_hi_expr_K:
2627 case widen_mult_lo_expr_K:
2628 case vec_pack_trunc_expr_K:
2629 case vec_pack_sat_expr_K:
2630 case vec_pack_fix_trunc_expr_K:
2631 case vec_extracteven_expr_K:
2632 case vec_extractodd_expr_K:
2633 case vec_interleavehigh_expr_K:
2634 case vec_interleavelow_expr_K:
2635 case extract_bit_expr_K:
2636 case sat_plus_expr_K:
2637 case sat_minus_expr_K:
2638 case extractvalue_expr_K:
2639 case extractelement_expr_K:
2665 exponent(e.
clone()),
2666 significand(f.
clone())
2681 " " + e->ToString() +
" " + f->ToString() +
"]<" +
2683 THROW_ASSERT(!s->isReal() && !e->isReal() && !f->isReal(),
"Real range components shouldn't be real ranges");
2689 if(vc->getBitWidth() == 32)
2694 else if(vc->getBitWidth() == 64)
2701 THROW_UNREACHABLE(
"Unhandled view convert bitwidth: could not transform " + vc->ToString() +
" into real range");
2712 return significand->zextOrTrunc(32)->Or(e)->Or(s);
2718 return significand->zextOrTrunc(64)->Or(e)->Or(s);
2741 const auto sign_bv =
sign->getBitValues(
true);
2742 auto exp_bv =
exponent->getBitValues(
true);
2743 if(exp_bv.size() <
exponent->getBitWidth())
2752 sig_bv.insert(sig_bv.begin(), exp_bv.begin(), exp_bv.end());
2753 sig_bv.insert(sig_bv.begin(), sign_bv.front());
2765 sign.reset(s->clone());
2782 auto rOther = RefcountCast<const RealRange>(other);
2783 return this->
getBitWidth() == other->getBitWidth() &&
sign->isSameRange(rOther->sign) &&
2849 if(
sign->isAnti() ||
sign->isConstant())
2851 const auto s =
sign->getUnsignedMin() ? 0 : 1;
2854 return RangeRef(this->
clone());
2859 if(
const auto rOther = RefcountCast<const RealRange>(other))
2863 const auto zeroContainedt = zeroEt->And(zeroMt);
2864 const auto zeroEo = rOther->exponent->Eq(RangeRef(
new Range(
Regular, rOther->exponent->getBitWidth(), 0, 0)), 1);
2866 rOther->significand->Eq(RangeRef(
new Range(
Regular, rOther->significand->getBitWidth(), 0, 0)), 1);
2867 const auto zeroContainedo = zeroEo->And(zeroMo);
2868 const auto zeroContained = zeroContainedt->And(zeroContainedo);
2869 if(!zeroContained->isConstant() || zeroContained->getUnsignedMin() == 1)
2871 return zeroContained->zextOrTrunc(_bw);
2873 return sign->Eq(rOther->sign, 1)
2874 ->And(
exponent->Eq(rOther->exponent, 1))
2883 return Eq(other, 1)->Not()->zextOrTrunc(_bw);
2888 #ifdef DEBUG_RANGE_OP 2889 PRINT_MSG(
"intersectWith-this: " << *
this << std::endl <<
"intersectWith-other: " << *other);
2891 THROW_ASSERT(other->isReal(),
"Real range should intersect with real range only");
2892 auto rrOther = RefcountCast<const RealRange>(other);
2893 return RangeRef(
new RealRange(
sign->intersectWith(rrOther->sign),
exponent->intersectWith(rrOther->exponent),
2894 significand->intersectWith(rrOther->significand)));
2899 #ifdef DEBUG_RANGE_OP 2900 PRINT_MSG(
"unionWith-this: " << *
this << std::endl <<
"unionWith-other: " << *other);
2902 THROW_ASSERT(other->isReal(),
"Real range should unite to real range only");
2903 auto rrOther = RefcountCast<const RealRange>(other);
2904 return RangeRef(
new RealRange(
sign->unionWith(rrOther->sign),
exponent->unionWith(rrOther->exponent),
2912 return RangeRef(this->
clone());
2915 RangeRef exponent64;
2927 exponent64.reset(
new Range(
Regular, 11, (
exponent->getUnsignedMin() + 896).extOrTrunc(11,
true),
2928 (
exponent->getUnsignedMax() + 896).extOrTrunc(11,
true)));
2939 return RangeRef(this->
clone());
2942 RangeRef exponent32;
2944 const auto min =
exponent->getUnsignedMin() - 896;
2945 const auto max =
exponent->getUnsignedMax() - 896;
2965 return RangeRef(
new RealRange(
sign, exponent32, significand32));
2970 THROW_ASSERT(bv.size() == 32 || bv.size() == 64,
"Floating-point bit_values must be exact");
2971 const std::deque<bit_lattice> bv_exp(bv.begin() + 1, bv.begin() + (bv.size() == 64 ? 12 : 9));
2972 const std::deque<bit_lattice> bv_sigf(bv.begin() + 1 +
static_cast<long>(bv_exp.size()), bv.end());
virtual bool isSameRange(const RangeConstRef &other) const
APInt & extOrTrunc(bw_t bw, bool sign)
bool isSingleElement() const override
void print(std::ostream &OS) const override
RangeRef zextOrTrunc(bw_t bitwidth) const
std::deque< bit_lattice > create_bitstring_from_constant(integer_cst_t value, unsigned long long len, bool signed_value)
Creates a bitstring from a constant input.
static APInt getSignedMinValue(bw_t bw)
RangeRef srem(const RangeConstRef &other) const
Range * clone() const override
APInt l
The lower bound of the range.
RangeRef getExponent() const
virtual void print(std::ostream &OS) const
APInt getSignedMin() const
virtual bool isConstant() const
bool isSameRange(const RangeConstRef &other) const override
RangeRef Ne(const RangeConstRef &other, bw_t bw) const override
RangeRef Ugt(const RangeConstRef &other, bw_t bw) const
RangeRef usat_add(const RangeConstRef &other) const
APInt getSignedMax() const
RangeRef Sgt(const RangeConstRef &other, bw_t bw) const
virtual bool isFullSet() const
RangeRef getRange() const
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
RangeRef SMax(const RangeConstRef &other) const
virtual RangeRef negate() const
std::string ToString() const
mathematical utility function not provided by standard libraries
const APInt & getUpper() const
bool isSameType(const RangeConstRef &other) const
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
RangeRef shl(const RangeConstRef &other) const
static const APInt MinDelta
RangeRef add(const RangeConstRef &other) const
exceptions managed by PandA
APInt u
The upper bound of the range.
static APInt getSignedMaxValue(bw_t bw)
RangeRef Xor(const RangeConstRef &other) const
void setSign(const RangeConstRef &s)
RangeRef Ult(const RangeConstRef &other, bw_t bw) const
static refcount< RealRange > fromBitValues(const std::deque< bit_lattice > &bv)
void mm(int in_a[A_ROWS][A_COLS], int in_b[A_COLS][B_COLS], int out_c[A_ROWS][B_COLS])
void setSignificand(const RangeConstRef &f)
bool isReal() const override
bool isFullSet() const override
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static void sign_reduce_bitstring(std::deque< bit_lattice > &bitstring, bool bitstring_is_signed)
Reduce the size of a bitstring erasing all but one most significant zeros in unsigned bitstring and a...
bw_t minBitwidth(bool sign) const
RangeRef unionWith(const RangeConstRef &other) const override
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
T ceil_log2(T x)
Return the smallest n such that 2**n >= X.
RangeRef And(const RangeConstRef &other) const
virtual bool isUnknown() const
virtual RangeRef abs() const
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
std::deque< bit_lattice > create_u_bitstring(size_t lenght)
Creates a bitstring containing bits initialized at <U>
static RangeRef makeSatisfyingCmpRegion(kind pred, const RangeConstRef &Other)
virtual bool isSingleElement() const
RangeRef udiv(const RangeConstRef &other) const
void normalizeRange(const APInt &lb, const APInt &ub, RangeType rType)
RangeRef sub(const RangeConstRef &other) const
bool isUnknown() const override
static const bw_t max_digits
static APInt getMaxValue(bw_t bw)
APInt getUnsignedMin() const
virtual void setUnknown()
void setUnknown() override
RangeRef toFloat64() const
RangeRef abs() const override
RealRange(const Range &s, const Range &e, const Range &f)
RangeRef mul(const RangeConstRef &other) const
Classes specification of the tree_node data structures.
RangeRef getSignificand() const
bool isEmpty() const override
#define RETURN_EMPTY_ON_EMPTY(b)
RangeRef Sge(const RangeConstRef &other, bw_t bw) const
RangeRef Or(const RangeConstRef &other) const
bw_t bw
the range bit-width
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
void setExponent(const RangeConstRef &e)
virtual RangeRef intersectWith(const RangeConstRef &other) const
RangeType type
the range type
RangeRef truncate(bw_t bitwidth) const
#define CASE_MISCELLANEOUS
RangeRef sextOrTrunc(bw_t bitwidth) const
RangeRef UMin(const RangeConstRef &other) const
RangeRef shr(const RangeConstRef &other, bool sign) const
virtual RangeRef Eq(const RangeConstRef &other, bw_t bw) const
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
RangeRef Uge(const RangeConstRef &other, bw_t bw) const
RangeRef SMin(const RangeConstRef &other) const
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Range(RangeType type, bw_t bw)
APInt getUnsignedMax() const
virtual RangeRef unionWith(const RangeConstRef &other) const
RangeRef Slt(const RangeConstRef &other, bw_t bw) const
#define RETURN_UNKNOWN_ON_UNKNOWN(b)
static bw_t neededBits(const APInt &a, const APInt &b, bool sign)
static APInt getMinValue(bw_t bw)
RangeRef UMax(const RangeConstRef &other) const
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
std::ostream & operator<<(std::ostream &OS, const Range &R)
static std::deque< bit_lattice > sign_extend_bitstring(const std::deque< bit_lattice > &bitstring, bool bitstring_is_signed, size_t final_size)
Extends a bitstring.
RangeRef usat_sub(const RangeConstRef &other) const
RangeRef urem(const RangeConstRef &other) const
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
const APInt & getLower() const
RangeRef Ule(const RangeConstRef &other, bw_t bw) const
RangeRef sat_sub(const RangeConstRef &other) const
RangeRef Sle(const RangeConstRef &other, bw_t bw) const
virtual bool isEmpty() const
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
virtual RangeRef Ne(const RangeConstRef &other, bw_t bw) const
RangeRef Eq(const RangeConstRef &other, bw_t bw) const override
static RangeRef fromBitValues(const std::deque< bit_lattice > &bv, bw_t bitwidth, bool isSigned)
std::deque< bit_lattice > getBitValues(bool) const override
RangeRef intersectWith(const RangeConstRef &other) const override
bool isConstant() const override
virtual bool isReal() const
virtual RangeRef getAnti() const
RangeRef sdiv(const RangeConstRef &other) const
virtual Range * clone() const
RangeRef getAnti() const override
virtual std::deque< bit_lattice > getBitValues(bool isSigned) const
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
RangeRef toFloat32() const
RangeRef sat_add(const RangeConstRef &other) const
RangeRef negate() const override
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...