Skip to content

Commit 1684f1e

Browse files
committed
Simplify byte_extract(byte_update(...)) when extracting from update
We can simplify byte_extract(byte_update(op, offset_u, value), offset_e)) to byte_extract(value, offset_e - offset_u) when the extracted range fully lies within the updated value. This simplification applies on our havoc_slice/test_struct_union_{b,d}_slice.desc tests.
1 parent a531056 commit 1684f1e

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

src/util/simplify_expr.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -1744,6 +1744,31 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
17441744
}
17451745
}
17461746

1747+
// byte_extract(byte_update(root, offset_u, value), offset_e) so that the
1748+
// extracted range fully lies within the update value simplifies to
1749+
// byte_extract(value, offset_e - offset_u)
1750+
if(
1751+
expr.op().id() == ID_byte_update_big_endian ||
1752+
expr.op().id() == ID_byte_update_little_endian)
1753+
{
1754+
const byte_update_exprt &bu = to_byte_update_expr(expr.op());
1755+
const auto update_offset = numeric_cast<mp_integer>(bu.offset());
1756+
const auto update_size = pointer_offset_bits(bu.value().type(), ns);
1757+
1758+
if(
1759+
el_size.has_value() && update_offset.has_value() &&
1760+
update_size.has_value() && *offset >= *update_offset &&
1761+
*offset * expr.get_bits_per_byte() + *el_size <=
1762+
*update_offset * bu.get_bits_per_byte() + *update_size)
1763+
{
1764+
auto tmp = expr;
1765+
tmp.op() = bu.value();
1766+
tmp.offset() =
1767+
from_integer(*offset - *update_offset, expr.offset().type());
1768+
return changed(simplify_byte_extract(tmp)); // recursive call
1769+
}
1770+
}
1771+
17471772
// don't do any of the following if endianness doesn't match, as
17481773
// bytes need to be swapped
17491774
if(

0 commit comments

Comments
 (0)