@@ -1621,19 +1621,14 @@ static exprt lower_byte_update_array_vector_unbounded(
16211621 plus_exprt{last_index, from_integer (1 , last_index.type ())}}};
16221622
16231623 // The actual value of a partial update at the end.
1624- exprt last_update_value = lower_byte_operators (
1624+ exprt last_update_value = lower_byte_update (
16251625 byte_update_exprt{
16261626 src.id (),
16271627 index_exprt{src.op (), last_index},
1628- from_integer (0 , src.offset ().type ()),
1629- byte_extract_exprt{
1630- extract_opcode,
1631- value_as_byte_array,
1632- mult_exprt{
1633- typecast_exprt::conditional_cast (last_index, subtype_size.type ()),
1634- subtype_size},
1635- src.get_bits_per_byte (),
1636- array_typet{bv_typet{src.get_bits_per_byte ()}, tail_size}},
1628+ unary_minus_exprt{mult_exprt{
1629+ typecast_exprt::conditional_cast (last_index, subtype_size.type ()),
1630+ subtype_size}},
1631+ value_as_byte_array,
16371632 src.get_bits_per_byte ()},
16381633 ns);
16391634
@@ -1675,10 +1670,6 @@ static exprt lower_byte_update_array_vector_non_const(
16751670 const optionalt<exprt> &non_const_update_bound,
16761671 const namespacet &ns)
16771672{
1678- const irep_idt extract_opcode = src.id () == ID_byte_update_little_endian
1679- ? ID_byte_extract_little_endian
1680- : ID_byte_extract_big_endian;
1681-
16821673 // do all arithmetic below using index/offset types - the array theory
16831674 // back-end is really picky about indices having the same type
16841675 auto subtype_size_opt = size_of_expr (subtype, ns);
@@ -1699,6 +1690,8 @@ static exprt lower_byte_update_array_vector_non_const(
16991690
17001691 // compute the number of bytes (from the update value) that are going to be
17011692 // consumed for updating the first element
1693+ const exprt update_size =
1694+ from_integer (value_as_byte_array.operands ().size (), subtype_size.type ());
17021695 exprt initial_bytes = minus_exprt{subtype_size, update_offset};
17031696 exprt update_bound;
17041697 if (non_const_update_bound.has_value ())
@@ -1711,28 +1704,23 @@ static exprt lower_byte_update_array_vector_non_const(
17111704 DATA_INVARIANT (
17121705 value_as_byte_array.id () == ID_array,
17131706 " value should be an array expression if the update bound is constant" );
1714- update_bound =
1715- from_integer (value_as_byte_array.operands ().size (), initial_bytes.type ());
1707+ update_bound = update_size;
17161708 }
17171709 initial_bytes =
17181710 if_exprt{binary_predicate_exprt{initial_bytes, ID_lt, update_bound},
17191711 initial_bytes,
17201712 update_bound};
17211713 simplify (initial_bytes, ns);
17221714
1723- // encode the first update: update the original element at first_index with
1724- // initial_bytes-many bytes extracted from value_as_byte_array
1725- exprt first_update_value = lower_byte_operators (
1715+ // encode the first update: update the original element at first_index (the
1716+ // actual update will only be initial_bytes-many bytes from
1717+ // value_as_byte_array)
1718+ exprt first_update_value = lower_byte_update (
17261719 byte_update_exprt{
17271720 src.id (),
17281721 index_exprt{src.op (), first_index},
17291722 update_offset,
1730- byte_extract_exprt{
1731- extract_opcode,
1732- value_as_byte_array,
1733- from_integer (0 , src.offset ().type ()),
1734- src.get_bits_per_byte (),
1735- array_typet{bv_typet{src.get_bits_per_byte ()}, initial_bytes}},
1723+ value_as_byte_array,
17361724 src.get_bits_per_byte ()},
17371725 ns);
17381726
@@ -1768,63 +1756,45 @@ static exprt lower_byte_update_array_vector_non_const(
17681756
17691757 with_exprt result{src.op (), first_index, first_update_value};
17701758
1771- std::size_t i = 1 ;
1772- for (; offset + step_size <= value_as_byte_array.operands ().size ();
1773- offset += step_size, ++i)
1774- {
1759+ auto lower_byte_update_array_vector_non_const_one_element =
1760+ [&src,
1761+ &first_index,
1762+ &initial_bytes,
1763+ &subtype_size,
1764+ &value_as_byte_array,
1765+ &ns,
1766+ &result](std::size_t i) -> void {
17751767 exprt where = simplify_expr (
17761768 plus_exprt{first_index, from_integer (i, first_index.type ())}, ns);
17771769
1778- exprt offset_expr = simplify_expr (
1779- plus_exprt{
1770+ exprt neg_offset_expr = simplify_expr (
1771+ unary_minus_exprt{ plus_exprt{
17801772 initial_bytes,
1781- mult_exprt{subtype_size, from_integer (i - 1 , subtype_size.type ())}},
1773+ mult_exprt{subtype_size, from_integer (i - 1 , subtype_size.type ())}}} ,
17821774 ns);
17831775
1784- exprt element = lower_byte_operators (
1776+ exprt element = lower_byte_update (
17851777 byte_update_exprt{
17861778 src.id (),
17871779 index_exprt{src.op (), where},
1788- from_integer (0 , src.offset ().type ()),
1789- byte_extract_exprt{
1790- extract_opcode,
1791- value_as_byte_array,
1792- std::move (offset_expr),
1793- src.get_bits_per_byte (),
1794- array_typet{bv_typet{src.get_bits_per_byte ()}, subtype_size}},
1780+ neg_offset_expr,
1781+ value_as_byte_array,
17951782 src.get_bits_per_byte ()},
17961783 ns);
17971784
17981785 result.add_to_operands (std::move (where), std::move (element));
1786+ };
1787+
1788+ std::size_t i = 1 ;
1789+ for (; offset + step_size <= value_as_byte_array.operands ().size ();
1790+ offset += step_size, ++i)
1791+ {
1792+ lower_byte_update_array_vector_non_const_one_element (i);
17991793 }
18001794
18011795 // do the tail
18021796 if (offset < value_as_byte_array.operands ().size ())
1803- {
1804- const std::size_t tail_size =
1805- value_as_byte_array.operands ().size () - offset;
1806-
1807- exprt where = simplify_expr (
1808- plus_exprt{first_index, from_integer (i, first_index.type ())}, ns);
1809-
1810- exprt element = lower_byte_operators (
1811- byte_update_exprt{
1812- src.id (),
1813- index_exprt{src.op (), where},
1814- from_integer (0 , src.offset ().type ()),
1815- byte_extract_exprt{
1816- extract_opcode,
1817- value_as_byte_array,
1818- from_integer (offset, src.offset ().type ()),
1819- src.get_bits_per_byte (),
1820- array_typet{
1821- bv_typet{src.get_bits_per_byte ()},
1822- from_integer (tail_size, size_type ())}},
1823- src.get_bits_per_byte ()},
1824- ns);
1825-
1826- result.add_to_operands (std::move (where), std::move (element));
1827- }
1797+ lower_byte_update_array_vector_non_const_one_element (i);
18281798
18291799 return simplify_expr (std::move (result), ns);
18301800}
@@ -2333,9 +2303,14 @@ static exprt lower_byte_update(
23332303 if_exprt mask_shifted{
23342304 offset_ge_zero,
23352305 shl_exprt{mask, offset_in_bits},
2336- lshr_exprt{mask, offset_in_bits}};
2306+ lshr_exprt{mask, unary_minus_exprt{ offset_in_bits} }};
23372307 if (!is_little_endian)
2308+ {
23382309 mask_shifted.true_case ().swap (mask_shifted.false_case ());
2310+ to_shift_expr (mask_shifted.true_case ())
2311+ .distance ()
2312+ .swap (to_shift_expr (mask_shifted.false_case ()).distance ());
2313+ }
23392314
23402315 // original_bits &= ~mask
23412316 bitand_exprt bitand_expr{val_before, bitnot_exprt{mask_shifted}};
@@ -2365,9 +2340,14 @@ static exprt lower_byte_update(
23652340 if_exprt value_shifted{
23662341 offset_ge_zero,
23672342 shl_exprt{zero_extended, offset_in_bits},
2368- lshr_exprt{zero_extended, offset_in_bits}};
2343+ lshr_exprt{zero_extended, unary_minus_exprt{ offset_in_bits} }};
23692344 if (!is_little_endian)
2345+ {
23702346 value_shifted.true_case ().swap (value_shifted.false_case ());
2347+ to_shift_expr (value_shifted.true_case ())
2348+ .distance ()
2349+ .swap (to_shift_expr (value_shifted.false_case ()).distance ());
2350+ }
23712351
23722352 // original_bits |= newvalue
23732353 bitor_exprt bitor_expr{bitand_expr, value_shifted};
0 commit comments