@@ -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