44 struct simplify_expr_cachet
48 typedef std::unordered_map<
51 typedef std::unordered_map<exprt, exprt, irep_hash> containert;
54 containert container_normal;
56 containert &container()
58 return container_normal;
62 simplify_expr_cachet simplify_expr_cache;
71 if(type.
id()==ID_floatbv)
77 else if(type.
id()==ID_signedbv ||
78 type.
id()==ID_unsignedbv)
80 auto value = numeric_cast<mp_integer>(
to_unary_expr(expr).op());
105 if(type.
id()==ID_floatbv)
110 else if(type.
id()==ID_signedbv ||
111 type.
id()==ID_unsignedbv)
113 const auto value = numeric_cast<mp_integer>(expr.
op());
114 if(value.has_value())
133 if(op_type.
id() == ID_signedbv || op_type.
id() == ID_unsignedbv)
137 std::size_t result = 0;
139 for(std::size_t i = 0; i < width; i++)
158 if(!const_bits_opt.has_value())
162 std::size_t n_leading_zeros = const_bits_opt->rfind(
'1');
163 if(n_leading_zeros == std::string::npos)
168 n_leading_zeros = const_bits_opt->size();
171 n_leading_zeros = const_bits_opt->size() - n_leading_zeros - 1;
184 if(!const_bits_opt.has_value())
188 std::size_t n_trailing_zeros = const_bits_opt->find(
'1');
189 if(n_trailing_zeros == std::string::npos)
194 n_trailing_zeros = const_bits_opt->size();
208 if(!const_bits_opt.has_value())
212 std::size_t first_one_bit = const_bits_opt->find(
'1');
213 if(first_one_bit == std::string::npos)
263 const auto first_value_opt =
273 const auto second_value_opt =
276 if(!second_value_opt)
284 const bool includes =
310 const auto numeric_length =
347 const bool first_shorter = s1_size < s2_size;
352 auto it_pair = std::mismatch(ops1.begin(), ops1.end(), ops2.begin());
354 if(it_pair.first == ops1.end())
363 first_shorter ? char1 - char2 : char2 - char1, expr.
type());
375 const bool search_from_end)
377 std::size_t starting_index = 0;
382 auto &starting_index_expr = expr.
arguments().at(2);
384 if(starting_index_expr.id() != ID_constant)
395 starting_index = numeric_cast_v<std::size_t>(idx);
410 const auto search_string_size = s1_data.
operands().size();
411 if(starting_index >= search_string_size)
416 unsigned long starting_offset =
417 starting_index > 0 ? (search_string_size - 1) - starting_index : 0;
440 ? starting_index > 0 ? starting_index : search_string_size
446 auto end = std::prev(s1_data.
operands().end(), starting_offset);
447 auto it = std::find_end(
454 std::distance(s1_data.
operands().begin(), it), expr.
type());
458 auto it = std::search(
459 std::next(s1_data.
operands().begin(), starting_index),
466 std::distance(s1_data.
operands().begin(), it), expr.
type());
469 else if(expr.
arguments().at(1).id() == ID_constant)
474 const auto c1_val = numeric_cast_v<mp_integer>(c1);
476 auto pred = [&](
const exprt &c2) {
479 return c1_val == c2_val;
484 auto it = std::find_if(
485 std::next(s1_data.
operands().rbegin(), starting_offset),
490 std::distance(s1_data.
operands().begin(), it.base() - 1),
495 auto it = std::find_if(
496 std::next(s1_data.
operands().begin(), starting_index),
501 std::distance(s1_data.
operands().begin(), it), expr.
type());
521 if(expr.
arguments().at(1).id() != ID_constant)
539 const auto i_opt = numeric_cast<std::size_t>(index);
541 if(!i_opt || *i_opt >= char_seq.
operands().size())
548 if(c.type() != expr.
type())
559 auto &operands = string_data.
operands();
560 for(
auto &operand : operands)
563 auto character = numeric_cast_v<unsigned int>(constant_value);
569 if(isalpha(character))
571 if(isupper(character))
573 from_integer(tolower(character), constant_value.type());
595 const auto first_value_opt =
605 const auto second_value_opt =
608 if(!second_value_opt)
621 bool is_equal = first_value == second_value;
640 const auto first_value_opt =
650 const auto second_value_opt =
653 if(!second_value_opt)
664 if(offset.id() != ID_constant)
672 offset_int + second_value.
operands().size();
675 exprt::operandst::const_iterator second_it =
677 for(
const auto &first_op : first_value.
operands())
681 else if(second_it == second_value.
operands().end())
683 else if(first_op != *second_it)
712 if(func_id == ID_cprover_string_startswith_func)
716 else if(func_id == ID_cprover_string_endswith_func)
720 else if(func_id == ID_cprover_string_is_empty_func)
724 else if(func_id == ID_cprover_string_compare_to_func)
728 else if(func_id == ID_cprover_string_index_of_func)
732 else if(func_id == ID_cprover_string_char_at_func)
736 else if(func_id == ID_cprover_string_contains_func)
740 else if(func_id == ID_cprover_string_last_index_of_func)
744 else if(func_id == ID_cprover_string_equals_ignore_case_func)
759 if(expr.
op().
id() == ID_infinity)
764 return std::move(tmp);
771 (expr_type.
id() == ID_unsignedbv || expr_type.
id() == ID_signedbv) &&
781 expr_type.
id() == ID_pointer && expr.
op().
id() == ID_typecast &&
782 (op_type.
id() == ID_signedbv || op_type.
id() == ID_unsignedbv) &&
786 auto new_expr = expr;
798 if(expr_type.
id()==ID_bool)
803 op_type.
id() == ID_floatbv ? ID_ieee_float_notequal : ID_notequal,
811 op_type.
id() == ID_bool &&
812 (expr_type.
id() == ID_signedbv || expr_type.
id() == ID_unsignedbv ||
813 expr_type.
id() == ID_c_bool || expr_type.
id() == ID_c_bit_field))
832 const auto &typecast = expr_checked_cast<typecast_exprt>(expr.
op());
833 if(typecast.op().type()==expr_type)
835 return typecast.op();
841 if(expr_type.
id()==ID_c_bool &&
842 op_type.
id()!=ID_bool)
846 auto new_expr = expr;
860 return std::move(tmp);
866 expr_type.
id() == ID_pointer && expr.
op().
id() == ID_typecast &&
867 op_type.
id() == ID_pointer)
869 auto new_expr = expr;
877 (expr_type.
id() == ID_signedbv || expr_type.
id() == ID_unsignedbv) &&
878 expr.
op().
id() == ID_typecast && expr.
op().
operands().size() == 1 &&
879 op_type.
id() == ID_pointer)
884 auto outer_cast = expr;
893 (expr_type.
id() == ID_signedbv || expr_type.
id() == ID_unsignedbv) &&
894 op_type.
id() == ID_pointer && expr.
op().
id() == ID_plus &&
900 (op_plus_expr.op0().id() == ID_typecast &&
902 (op_plus_expr.op0().is_constant() &&
907 if(sub_size.has_value())
909 auto new_expr = expr;
914 if(*sub_size == 0 || *sub_size == 1)
915 new_expr.op() = offset_expr;
936 if((expr_type.
id()==ID_signedbv || expr_type.
id()==ID_unsignedbv) &&
937 (op_type.
id()==ID_signedbv || op_type.
id()==ID_unsignedbv))
947 if(op_id==ID_plus || op_id==ID_minus || op_id==ID_mult ||
948 op_id==ID_unary_minus ||
949 op_id==ID_bitxor || op_id==ID_bitor || op_id==ID_bitand)
968 else if(op_id==ID_ashr || op_id==ID_lshr || op_id==ID_shl)
978 (expr_type.
id() == ID_signedbv || expr_type.
id() == ID_unsignedbv) &&
979 op_type.
id() == ID_pointer && expr.
op().
id() == ID_plus)
984 if(step.has_value() && *step != 0)
987 auto new_expr = expr;
989 new_expr.
op().
type() = size_t_type;
991 for(
auto &op : new_expr.op().operands())
994 if(op.type().id() != ID_pointer && *step > 1)
999 op = std::move(new_op);
1010 if(expr.
op().
id()==ID_if &&
1017 auto new_expr=
if_exprt(expr.
op().
op0(), tmp_op1, tmp_op2, expr_type);
1019 return std::move(new_expr);
1024 const exprt &operand = expr.
op();
1032 typet c_sizeof_type=
1033 static_cast<const typet &
>(operand.
find(ID_C_c_sizeof_type));
1035 if(op_type_id==ID_integer ||
1036 op_type_id==ID_natural)
1042 if(expr_type_id==ID_bool)
1047 if(expr_type_id==ID_unsignedbv ||
1048 expr_type_id==ID_signedbv ||
1049 expr_type_id==ID_c_enum ||
1050 expr_type_id==ID_c_bit_field ||
1051 expr_type_id==ID_integer)
1055 else if(expr_type_id == ID_c_enum_tag)
1058 if(!c_enum_type.is_incomplete())
1061 tmp.
type() = expr_type;
1062 return std::move(tmp);
1066 else if(op_type_id==ID_rational)
1069 else if(op_type_id==ID_real)
1072 else if(op_type_id==ID_bool)
1074 if(expr_type_id==ID_unsignedbv ||
1075 expr_type_id==ID_signedbv ||
1076 expr_type_id==ID_integer ||
1077 expr_type_id==ID_natural ||
1078 expr_type_id==ID_rational ||
1079 expr_type_id==ID_c_bool ||
1080 expr_type_id==ID_c_enum ||
1081 expr_type_id==ID_c_bit_field)
1092 else if(expr_type_id==ID_c_enum_tag)
1095 if(!c_enum_type.is_incomplete())
1097 unsigned int_value = operand.
is_true() ? 1u : 0u;
1099 tmp.
type()=expr_type;
1100 return std::move(tmp);
1103 else if(expr_type_id==ID_pointer &&
1110 else if(op_type_id==ID_unsignedbv ||
1111 op_type_id==ID_signedbv ||
1112 op_type_id==ID_c_bit_field ||
1113 op_type_id==ID_c_bool)
1120 if(expr_type_id==ID_bool)
1125 if(expr_type_id==ID_c_bool)
1130 if(expr_type_id==ID_integer)
1135 if(expr_type_id==ID_natural)
1143 if(expr_type_id==ID_unsignedbv ||
1144 expr_type_id==ID_signedbv ||
1145 expr_type_id==ID_bv ||
1146 expr_type_id==ID_c_bit_field)
1151 result.set(ID_C_c_sizeof_type, c_sizeof_type);
1153 return std::move(result);
1156 if(expr_type_id==ID_c_enum_tag)
1159 if(!c_enum_type.is_incomplete())
1162 tmp.
type()=expr_type;
1163 return std::move(tmp);
1167 if(expr_type_id==ID_c_enum)
1172 if(expr_type_id==ID_fixedbv)
1184 if(expr_type_id==ID_floatbv)
1196 if(expr_type_id==ID_rational)
1202 else if(op_type_id==ID_fixedbv)
1204 if(expr_type_id==ID_unsignedbv ||
1205 expr_type_id==ID_signedbv)
1211 else if(expr_type_id==ID_fixedbv)
1218 else if(expr_type_id == ID_bv)
1224 else if(op_type_id==ID_floatbv)
1228 if(expr_type_id==ID_unsignedbv ||
1229 expr_type_id==ID_signedbv)
1234 else if(expr_type_id==ID_floatbv)
1240 else if(expr_type_id==ID_fixedbv)
1250 else if(expr_type_id == ID_bv)
1255 else if(op_type_id==ID_bv)
1258 expr_type_id == ID_unsignedbv || expr_type_id == ID_signedbv ||
1259 expr_type_id == ID_c_enum || expr_type_id == ID_c_enum_tag ||
1260 expr_type_id == ID_c_bit_field)
1264 if(expr_type_id != ID_c_enum_tag)
1270 result.type() = tag_type;
1271 return std::move(result);
1274 else if(expr_type_id == ID_floatbv)
1279 ieee_float.unpack(int_value);
1280 return ieee_float.to_expr();
1282 else if(expr_type_id == ID_fixedbv)
1287 fixedbv.set_value(int_value);
1288 return fixedbv.to_expr();
1291 else if(op_type_id==ID_c_enum_tag)
1293 const typet &base_type =
1295 if(base_type.
id()==ID_signedbv || base_type.
id()==ID_unsignedbv)
1298 auto new_expr = expr;
1299 new_expr.
op().
type() = base_type;
1303 else if(op_type_id==ID_c_enum)
1306 if(base_type.
id()==ID_signedbv || base_type.
id()==ID_unsignedbv)
1309 auto new_expr = expr;
1310 new_expr.
op().
type() = base_type;
1315 else if(operand.
id()==ID_typecast)
1320 op_type_id == expr_type_id &&
1321 (expr_type_id == ID_unsignedbv || expr_type_id == ID_signedbv) &&
1325 auto new_expr = expr;
1331 else if(operand.
id()==ID_address_of)
1337 o.
type().
id() == ID_array &&
1355 if(pointer.
type().
id()!=ID_pointer)
1358 if(pointer.
id()==ID_if && pointer.
operands().size()==3)
1362 auto tmp_op1 = expr;
1366 auto tmp_op2 = expr;
1370 if_exprt tmp{if_expr.
cond(), tmp_op1_result, tmp_op2_result};
1375 if(pointer.
id()==ID_address_of)
1383 pointer.
id() == ID_plus && pointer.
operands().size() == 2 &&
1391 if(address_of.
object().
id()==ID_index)
1416 bool no_change =
true;
1422 auto with_expr = expr;
1424 const typet old_type_followed =
ns.
follow(with_expr.old().type());
1428 if(old_type_followed.
id() == ID_struct)
1430 if(with_expr.old().id() == ID_struct || with_expr.old().id() == ID_constant)
1432 while(with_expr.operands().size() > 1)
1435 with_expr.where().get(ID_component_name);
1437 if(!
to_struct_type(old_type_followed).has_component(component_name))
1440 std::size_t number =
1443 if(number >= with_expr.old().operands().size())
1446 with_expr.old().operands()[number].swap(with_expr.new_value());
1448 with_expr.operands().erase(++with_expr.operands().begin());
1449 with_expr.operands().erase(++with_expr.operands().begin());
1456 with_expr.old().type().id() == ID_array ||
1457 with_expr.old().type().id() == ID_vector)
1460 with_expr.old().id() == ID_array || with_expr.old().id() == ID_constant ||
1461 with_expr.old().id() == ID_vector)
1463 while(with_expr.operands().size() > 1)
1465 const auto i = numeric_cast<mp_integer>(with_expr.where());
1470 if(*i < 0 || *i >= with_expr.old().operands().size())
1473 with_expr.old().operands()[numeric_cast_v<std::size_t>(*i)].swap(
1474 with_expr.new_value());
1476 with_expr.operands().erase(++with_expr.operands().begin());
1477 with_expr.operands().erase(++with_expr.operands().begin());
1484 if(with_expr.operands().size() == 1)
1485 return with_expr.old();
1490 return std::move(with_expr);
1501 exprt *value_ptr=&updated_value;
1503 for(
const auto &e : designator)
1507 if(e.id()==ID_index_designator &&
1508 value_ptr->
id()==ID_array)
1515 if(*i < 0 || *i >= value_ptr->
operands().size())
1518 value_ptr = &value_ptr->
operands()[numeric_cast_v<std::size_t>(*i)];
1520 else if(e.id()==ID_member_designator &&
1521 value_ptr->
id()==ID_struct)
1524 e.get(ID_component_name);
1530 value_ptr = &designator_as_struct_expr.component(component_name,
ns);
1539 return updated_value;
1544 if(expr.
id()==ID_plus)
1546 if(expr.
type().
id()==ID_pointer)
1550 if(op.type().id() == ID_pointer)
1554 else if(expr.
id()==ID_typecast)
1557 const typet &op_type = typecast_expr.op().type();
1559 if(op_type.
id()==ID_pointer)
1564 else if(op_type.
id()==ID_signedbv || op_type.
id()==ID_unsignedbv)
1571 const exprt &casted_expr = typecast_expr.op();
1572 if(casted_expr.
id() == ID_plus && casted_expr.
operands().size() == 2)
1576 const exprt &cand = plus_expr.
op0().
id() == ID_typecast
1580 if(cand.
id() == ID_typecast)
1584 if(typecast_op.id() == ID_address_of)
1589 typecast_op.id() == ID_plus && typecast_op.operands().size() == 2 &&
1600 else if(expr.
id()==ID_address_of)
1604 if(
object.
id() == ID_index)
1610 else if(
object.
id() == ID_member)
1625 if(expr.
op().
id()==ID_if)
1636 if(el_size.has_value() && *el_size < 0)
1641 if(expr.
op().
id()==expr.
id())
1655 ((expr.
id() == ID_byte_extract_big_endian &&
1656 expr.
op().
id() == ID_byte_update_big_endian) ||
1657 (expr.
id() == ID_byte_extract_little_endian &&
1658 expr.
op().
id() == ID_byte_update_little_endian)) &&
1663 if(expr.
type() == op_byte_update.value().type())
1665 return op_byte_update.value();
1668 el_size.has_value() &&
1672 tmp.
op() = op_byte_update.value();
1680 auto offset = numeric_cast<mp_integer>(expr.
offset());
1681 if(!offset.has_value() || *offset < 0)
1687 *offset == 0 && ((expr.
id() == ID_byte_extract_little_endian &&
1690 (expr.
id() == ID_byte_extract_big_endian &&
1700 expr.
type().
id() == ID_pointer && expr.
op().
type().
id() == ID_pointer)
1708 if(!el_size.has_value() || *el_size == 0)
1711 if(expr.
op().
id()==ID_array_of &&
1720 if(!const_bits_opt.has_value())
1723 std::string const_bits=const_bits_opt.value();
1725 DATA_INVARIANT(!const_bits.empty(),
"bit representation must be non-empty");
1728 while(
mp_integer(const_bits.size()) < *offset * 8 + *el_size)
1729 const_bits+=const_bits;
1731 std::string el_bits = std::string(
1733 numeric_cast_v<std::size_t>(*offset * 8),
1734 numeric_cast_v<std::size_t>(*el_size));
1737 el_bits, expr.
type(), expr.
id() == ID_byte_extract_little_endian,
ns);
1740 return std::move(*tmp);
1745 expr.
op().
id() == ID_array_of && (*offset * 8) % (*el_size) == 0 &&
1760 const bool struct_has_flexible_array_member =
has_subtype(
1762 [&](
const typet &type) {
1763 if(type.id() != ID_struct && type.id() != ID_struct_tag)
1766 const struct_typet &st = to_struct_type(ns.follow(type));
1767 const auto &comps = st.components();
1768 if(comps.empty() || comps.back().type().id() != ID_array)
1771 if(comps.back().type().get_bool(ID_C_flexible_array_member))
1775 numeric_cast<mp_integer>(to_array_type(comps.back().type()).size());
1776 return !size.has_value() || *size <= 1;
1780 bits.has_value() &&
mp_integer(bits->size()) >= *el_size + *offset * 8 &&
1781 !struct_has_flexible_array_member)
1783 std::string bits_cut = std::string(
1785 numeric_cast_v<std::size_t>(*offset * 8),
1786 numeric_cast_v<std::size_t>(*el_size));
1789 bits_cut, expr.
type(), expr.
id() == ID_byte_extract_little_endian,
ns);
1792 return std::move(*tmp);
1798 if(expr.
op().
id() == ID_struct || expr.
op().
id() == ID_union)
1800 if(expr.
type().
id() == ID_struct || expr.
type().
id() == ID_struct_tag)
1808 for(
const auto &comp : components)
1814 !component_bits.has_value() || *component_bits == 0 ||
1815 *component_bits % 8 != 0)
1821 auto member_offset_opt =
1824 if(!member_offset_opt.has_value())
1833 member_offset_opt.value(), expr.
offset().
type())});
1836 tmp.
type() = comp.type();
1837 tmp.offset() = new_offset;
1845 else if(expr.
type().
id() == ID_union || expr.
type().
id() == ID_union_tag)
1849 if(widest_member_opt.has_value())
1852 be.
type() = widest_member_opt->first.type();
1853 return union_exprt{widest_member_opt->first.get_name(),
1859 else if(expr.
op().
id() == ID_array)
1862 const auto &element_bit_width =
1864 if(element_bit_width.has_value() && *element_bit_width > 0)
1866 if(*offset > 0 && *offset * 8 % *element_bit_width == 0)
1868 const auto elements_to_erase =
1869 numeric_cast_v<std::size_t>((*offset * 8) / *element_bit_width);
1871 slice.operands().erase(
1872 slice.operands().begin(),
1873 slice.operands().begin() +
1874 std::min(elements_to_erase,
slice.operands().size()));
1875 slice.type().size() =
1882 else if(*offset == 0 && *el_size % *element_bit_width == 0)
1884 const auto elements_to_keep =
1885 numeric_cast_v<std::size_t>(*el_size / *element_bit_width);
1887 if(
slice.operands().size() > elements_to_keep)
1889 slice.operands().resize(elements_to_keep);
1890 slice.type().size() =
1903 if(!subexpr.has_value() || subexpr.value() == expr)
1915 expr.
id() == expr.
op().
id() &&
1921 return std::move(tmp);
1924 const exprt &root = expr.
op();
1932 offset.
is_zero() && val_size.has_value() && *val_size > 0 &&
1933 root_size.has_value() && *root_size > 0 && *val_size >= *root_size)
1936 expr.
id()==ID_byte_update_little_endian ?
1937 ID_byte_extract_little_endian :
1938 ID_byte_extract_big_endian,
1939 value, offset, expr.
type());
1945 const auto offset_int = numeric_cast<mp_integer>(offset);
1947 root_size.has_value() && *root_size >= 0 && val_size.has_value() &&
1948 *val_size >= 0 && offset_int.has_value() && *offset_int >= 0 &&
1949 *offset_int * 8 + *val_size <= *root_size)
1952 expr2bits(root, expr.
id() == ID_byte_update_little_endian,
ns);
1954 if(root_bits.has_value())
1956 const auto val_bits =
1957 expr2bits(value, expr.
id() == ID_byte_update_little_endian,
ns);
1959 if(val_bits.has_value())
1962 numeric_cast_v<std::size_t>(*offset_int * 8),
1963 numeric_cast_v<std::size_t>(*val_size),
1969 expr.
id() == ID_byte_update_little_endian,
1973 return std::move(*tmp);
1986 if(expr.
id()!=ID_byte_update_little_endian)
1989 if(value.
id()==ID_with)
1993 if(with.
old().
id()==ID_byte_extract_little_endian)
2000 if(!(root==extract.
op()))
2002 if(!(offset==extract.
offset()))
2006 if(tp.
id()==ID_struct)
2013 if(c_type.
id() == ID_c_bit_field || c_type.
id() == ID_bool)
2028 tmp.set_value(std::move(new_value));
2033 else if(tp.
id()==ID_array)
2039 exprt index_offset =
2053 tmp.set_value(std::move(new_value));
2061 if(!offset_int.has_value() || *offset_int < 0)
2067 if(!val_size.has_value() || *val_size == 0)
2072 if(op_type.
id()==ID_struct)
2091 if(!m_offset.has_value())
2098 if(!m_size_bits.has_value() || *m_size_bits == 0 || (*m_size_bits) % 8 != 0)
2104 mp_integer m_size_bytes = (*m_size_bits) / 8;
2107 if(*m_offset + m_size_bytes <= *offset_int)
2111 update_size.has_value() && *update_size > 0 &&
2112 *m_offset >= *offset_int + *update_size)
2120 exprt member_name(ID_member_name);
2121 member_name.
set(ID_component_name,
component.get_name());
2126 *m_offset < *offset_int ||
2127 (*m_offset == *offset_int && update_size.has_value() &&
2128 *update_size > 0 && m_size_bytes > *update_size))
2131 ID_byte_update_little_endian,
2139 update_size.has_value() && *update_size > 0 &&
2140 *m_offset + m_size_bytes > *offset_int + *update_size)
2149 ID_byte_extract_little_endian,
2164 if(root.
id()==ID_array)
2169 if(!el_size.has_value() || *el_size == 0 ||
2170 (*el_size) % 8 != 0 || (*val_size) % 8 != 0)
2180 if(*offset_int * 8 + (*val_size) <= m_offset_bits)
2183 if(*offset_int * 8 < m_offset_bits + *el_size)
2185 mp_integer bytes_req = (m_offset_bits + *el_size) / 8 - *offset_int;
2186 bytes_req-=val_offset;
2187 if(val_offset + bytes_req > (*val_size) / 8)
2188 bytes_req = (*val_size) / 8 - val_offset;
2191 ID_byte_extract_little_endian,
2201 *offset_int + val_offset - m_offset_bits / 8, offset.
type()),
2206 val_offset+=bytes_req;
2209 m_offset_bits += *el_size;
2212 return std::move(result);
2221 if(expr.
id() == ID_complex_real)
2225 if(complex_real_expr.op().id() == ID_complex)
2228 else if(expr.
id() == ID_complex_imag)
2232 if(complex_imag_expr.op().id() == ID_complex)
2266 op_type_id == ID_integer || op_type_id == ID_rational ||
2267 op_type_id == ID_real)
2276 if(op_type_id != ID_signedbv && op_type_id != ID_unsignedbv)
2282 const auto op0_value = numeric_cast<mp_integer>(expr.
op0());
2283 const auto op1_value = numeric_cast<mp_integer>(expr.
op1());
2284 if(!op0_value.has_value() || !op1_value.has_value())
2289 no_overflow_result = *op0_value + *op1_value;
2291 no_overflow_result = *op0_value - *op1_value;
2293 no_overflow_result = *op0_value * *op1_value;
2295 no_overflow_result = *op0_value << *op1_value;
2302 no_overflow_result < bv_type.smallest() ||
2303 no_overflow_result > bv_type.largest())
2321 op_type_id == ID_integer || op_type_id == ID_rational ||
2322 op_type_id == ID_real)
2327 if(op_type_id == ID_natural)
2331 if(op_type_id != ID_signedbv && op_type_id != ID_unsignedbv)
2337 const auto op_value = numeric_cast<mp_integer>(expr.
op());
2338 if(!op_value.has_value())
2343 no_overflow_result = -*op_value;
2350 no_overflow_result < bv_type.smallest() ||
2351 no_overflow_result > bv_type.largest())
2362 if(expr.
id() == ID_overflow_result_unary_minus)
2371 op_type_id == ID_integer || op_type_id == ID_rational ||
2372 op_type_id == ID_real)
2379 if(op_type_id == ID_natural)
2383 if(op_type_id != ID_signedbv && op_type_id != ID_unsignedbv)
2389 const auto op_value = numeric_cast<mp_integer>(expr.
op0());
2390 if(!op_value.has_value())
2398 no_overflow_result < bv_type.smallest() ||
2399 no_overflow_result > bv_type.largest())
2419 expr.
id() == ID_overflow_result_plus ||
2420 expr.
id() == ID_overflow_result_shl)
2424 else if(expr.
id() == ID_overflow_result_mult)
2433 expr.
id() == ID_overflow_result_plus ||
2434 expr.
id() == ID_overflow_result_minus ||
2435 expr.
id() == ID_overflow_result_shl)
2448 expr.
id() == ID_overflow_result_mult &&
2458 expr.
id() != ID_overflow_result_shl &&
2467 expr.
id() != ID_overflow_result_shl &&
2468 (op_type_id == ID_integer || op_type_id == ID_rational ||
2469 op_type_id == ID_real))
2472 expr.
id() == ID_overflow_result_plus
2474 : expr.
id() == ID_overflow_result_minus ? ID_minus : ID_mult;
2482 (expr.
id() == ID_overflow_result_plus ||
2483 expr.
id() == ID_overflow_result_mult) &&
2484 op_type_id == ID_natural)
2489 expr.
id() == ID_overflow_result_plus ? ID_plus : ID_mult,
2496 if(op_type_id != ID_signedbv && op_type_id != ID_unsignedbv)
2502 const auto op0_value = numeric_cast<mp_integer>(expr.
op0());
2503 const auto op1_value = numeric_cast<mp_integer>(expr.
op1());
2504 if(!op0_value.has_value() || !op1_value.has_value())
2508 if(expr.
id() == ID_overflow_result_plus)
2509 no_overflow_result = *op0_value + *op1_value;
2510 else if(expr.
id() == ID_overflow_result_minus)
2511 no_overflow_result = *op0_value - *op1_value;
2512 else if(expr.
id() == ID_overflow_result_mult)
2513 no_overflow_result = *op0_value * *op1_value;
2514 else if(expr.
id() == ID_overflow_result_shl)
2515 no_overflow_result = *op0_value << *op1_value;
2522 no_overflow_result < bv_type.smallest() ||
2523 no_overflow_result > bv_type.largest())
2544 if(expr.
id()==ID_address_of)
2548 else if(expr.
id()==ID_if)
2557 if(r_it.has_changed())
2585 if(expr.
id()==ID_typecast)
2589 else if(expr.
id()==ID_equal || expr.
id()==ID_notequal ||
2590 expr.
id()==ID_gt || expr.
id()==ID_lt ||
2591 expr.
id()==ID_ge || expr.
id()==ID_le)
2595 else if(expr.
id()==ID_if)
2599 else if(expr.
id()==ID_lambda)
2603 else if(expr.
id()==ID_with)
2607 else if(expr.
id()==ID_update)
2611 else if(expr.
id()==ID_index)
2615 else if(expr.
id()==ID_member)
2619 else if(expr.
id()==ID_byte_update_little_endian ||
2620 expr.
id()==ID_byte_update_big_endian)
2624 else if(expr.
id()==ID_byte_extract_little_endian ||
2625 expr.
id()==ID_byte_extract_big_endian)
2629 else if(expr.
id()==ID_pointer_object)
2633 else if(expr.
id() == ID_is_dynamic_object)
2637 else if(expr.
id() == ID_is_invalid_pointer)
2642 const auto object_size = expr_try_dynamic_cast<object_size_exprt>(expr))
2646 else if(expr.
id()==ID_good_pointer)
2650 else if(expr.
id()==ID_div)
2654 else if(expr.
id()==ID_mod)
2658 else if(expr.
id()==ID_bitnot)
2662 else if(expr.
id()==ID_bitand ||
2663 expr.
id()==ID_bitor ||
2664 expr.
id()==ID_bitxor)
2668 else if(expr.
id()==ID_ashr || expr.
id()==ID_lshr || expr.
id()==ID_shl)
2672 else if(expr.
id()==ID_power)
2676 else if(expr.
id()==ID_plus)
2680 else if(expr.
id()==ID_minus)
2684 else if(expr.
id()==ID_mult)
2688 else if(expr.
id()==ID_floatbv_plus ||
2689 expr.
id()==ID_floatbv_minus ||
2690 expr.
id()==ID_floatbv_mult ||
2691 expr.
id()==ID_floatbv_div)
2695 else if(expr.
id()==ID_floatbv_typecast)
2699 else if(expr.
id()==ID_unary_minus)
2703 else if(expr.
id()==ID_unary_plus)
2707 else if(expr.
id()==ID_not)
2711 else if(expr.
id()==ID_implies ||
2712 expr.
id()==ID_or || expr.
id()==ID_xor ||
2717 else if(expr.
id()==ID_dereference)
2721 else if(expr.
id()==ID_address_of)
2725 else if(expr.
id()==ID_pointer_offset)
2729 else if(expr.
id()==ID_extractbit)
2733 else if(expr.
id()==ID_concatenation)
2737 else if(expr.
id()==ID_extractbits)
2741 else if(expr.
id()==ID_ieee_float_equal ||
2742 expr.
id()==ID_ieee_float_notequal)
2746 else if(expr.
id() == ID_bswap)
2750 else if(expr.
id()==ID_isinf)
2754 else if(expr.
id()==ID_isnan)
2758 else if(expr.
id()==ID_isnormal)
2762 else if(expr.
id()==ID_abs)
2766 else if(expr.
id()==ID_sign)
2770 else if(expr.
id() == ID_popcount)
2774 else if(expr.
id() == ID_count_leading_zeros)
2778 else if(expr.
id() == ID_count_trailing_zeros)
2782 else if(expr.
id() == ID_find_first_set)
2786 else if(expr.
id() == ID_function_application)
2790 else if(expr.
id() == ID_complex_real || expr.
id() == ID_complex_imag)
2795 const auto binary_overflow =
2796 expr_try_dynamic_cast<binary_overflow_exprt>(expr))
2801 const auto unary_overflow =
2802 expr_try_dynamic_cast<unary_overflow_exprt>(expr))
2807 const auto overflow_result =
2808 expr_try_dynamic_cast<overflow_result_exprt>(expr))
2812 else if(expr.
id() == ID_bitreverse)
2817 if(!no_change_join_operands)
2823 # ifdef DEBUG_ON_DEMAND
2828 std::cout <<
"===== " << node.
id() <<
": " <<
format(node) <<
'\n'
2829 <<
" ---> " <<
format(
r.expr) <<
'\n';
2841 std::pair<simplify_expr_cachet::containert::iterator, bool>
2842 cache_result=simplify_expr_cache.container().
2843 insert(std::pair<exprt, exprt>(expr,
exprt()));
2845 if(!cache_result.second)
2847 const exprt &new_expr=cache_result.first->second;
2863 if(simplify_node_result.has_changed())
2866 tmp = simplify_node_result.expr;
2869 #ifdef USE_LOCAL_REPLACE_MAP
2871 replace_mapt::const_iterator it=local_replace_map.
find(tmp);
2872 if(it!=local_replace_map.end())
2878 if(!local_replace_map.empty() &&
2897 cache_result.first->second = tmp;
2900 return std::move(tmp);
2907 #ifdef DEBUG_ON_DEMAND
2909 std::cout <<
"TO-SIMP " <<
format(expr) <<
"\n";
2912 #ifdef DEBUG_ON_DEMAND
2914 std::cout <<
"FULLSIMP " <<
format(result.expr) <<
"\n";
2916 if(result.has_changed())