Skip to content

Commit c1ef4df

Browse files
authored
Merge pull request #7933 from tautschnig/features/simplify-be-bu
Simplify byte_extract(byte_update(...)) when extracting from update
2 parents db9c799 + a73353d commit c1ef4df

File tree

1 file changed

+39
-24
lines changed

1 file changed

+39
-24
lines changed

src/util/simplify_expr.cpp

+39-24
Original file line numberDiff line numberDiff line change
@@ -1709,37 +1709,52 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
17091709
if(!offset.has_value() || *offset < 0)
17101710
return unchanged(expr);
17111711

1712-
// byte_extract(byte_update(root, offset_u, value), offset_e) so that the
1713-
// update does not affect what is being extracted simplifies to
1714-
// byte_extract(root, offset_e)
1715-
if(
1716-
expr.op().id() == ID_byte_update_big_endian ||
1717-
expr.op().id() == ID_byte_update_little_endian)
1718-
{
1719-
const byte_update_exprt &bu = to_byte_update_expr(expr.op());
1720-
const auto update_offset = numeric_cast<mp_integer>(bu.offset());
1721-
if(el_size.has_value() && update_offset.has_value())
1712+
// try to simplify byte_extract(byte_update(...))
1713+
auto const bu = expr_try_dynamic_cast<byte_update_exprt>(expr.op());
1714+
optionalt<mp_integer> update_offset;
1715+
if(bu)
1716+
update_offset = numeric_cast<mp_integer>(bu->offset());
1717+
if(bu && el_size.has_value() && update_offset.has_value())
1718+
{
1719+
// byte_extract(byte_update(root, offset_u, value), offset_e) so that the
1720+
// update does not affect what is being extracted simplifies to
1721+
// byte_extract(root, offset_e)
1722+
//
1723+
// byte_extract(byte_update(root, offset_u, value), offset_e) so that the
1724+
// extracted range fully lies within the update value simplifies to
1725+
// byte_extract(value, offset_e - offset_u)
1726+
if(
1727+
*offset * expr.get_bits_per_byte() + *el_size <=
1728+
*update_offset * bu->get_bits_per_byte())
1729+
{
1730+
// extracting before the update
1731+
auto tmp = expr;
1732+
tmp.op() = bu->op();
1733+
return changed(simplify_byte_extract(tmp)); // recursive call
1734+
}
1735+
else if(
1736+
const auto update_size = pointer_offset_bits(bu->value().type(), ns))
17221737
{
17231738
if(
1724-
*offset * expr.get_bits_per_byte() + *el_size <=
1725-
*update_offset * bu.get_bits_per_byte())
1739+
*offset * expr.get_bits_per_byte() >=
1740+
*update_offset * bu->get_bits_per_byte() + *update_size)
17261741
{
1742+
// extracting after the update
17271743
auto tmp = expr;
1728-
tmp.op() = bu.op();
1744+
tmp.op() = bu->op();
17291745
return changed(simplify_byte_extract(tmp)); // recursive call
17301746
}
1731-
else
1747+
else if(
1748+
*offset >= *update_offset &&
1749+
*offset * expr.get_bits_per_byte() + *el_size <=
1750+
*update_offset * bu->get_bits_per_byte() + *update_size)
17321751
{
1733-
const auto update_size = pointer_offset_bits(bu.value().type(), ns);
1734-
if(
1735-
update_size.has_value() &&
1736-
*offset * expr.get_bits_per_byte() >=
1737-
*update_offset * bu.get_bits_per_byte() + *update_size)
1738-
{
1739-
auto tmp = expr;
1740-
tmp.op() = bu.op();
1741-
return changed(simplify_byte_extract(tmp)); // recursive call
1742-
}
1752+
// extracting from the update
1753+
auto tmp = expr;
1754+
tmp.op() = bu->value();
1755+
tmp.offset() =
1756+
from_integer(*offset - *update_offset, expr.offset().type());
1757+
return changed(simplify_byte_extract(tmp)); // recursive call
17431758
}
17441759
}
17451760
}

0 commit comments

Comments
 (0)