@@ -1709,37 +1709,52 @@ simplify_exprt::simplify_byte_extract(const byte_extract_exprt &expr)
1709
1709
if (!offset.has_value () || *offset < 0 )
1710
1710
return unchanged (expr);
1711
1711
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))
1722
1737
{
1723
1738
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 )
1726
1741
{
1742
+ // extracting after the update
1727
1743
auto tmp = expr;
1728
- tmp.op () = bu. op ();
1744
+ tmp.op () = bu-> op ();
1729
1745
return changed (simplify_byte_extract (tmp)); // recursive call
1730
1746
}
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)
1732
1751
{
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
1743
1758
}
1744
1759
}
1745
1760
}
0 commit comments