@@ -1205,30 +1205,64 @@ simplify_exprt::simplify_extractbits(const extractbits_exprt &expr)
12051205
12061206 return std::move (*result);
12071207 }
1208+ else if (*end == 0 && *start + 1 == *width)
1209+ {
1210+ typecast_exprt tc{expr.src (), expr.type ()};
1211+ return changed (simplify_typecast (tc));
1212+ }
12081213 else if (expr.src ().id () == ID_concatenation)
12091214 {
12101215 // the most-significant bit comes first in an concatenation_exprt, hence we
12111216 // count down
12121217 mp_integer offset = *width;
12131218
1219+ exprt::operandst new_operands;
1220+ new_operands.reserve (expr.src ().operands ().size ());
1221+ mp_integer new_index = *end;
1222+ mp_integer new_concat_width = 0 ;
1223+
12141224 for (const auto &op : expr.src ().operands ())
12151225 {
12161226 auto op_width = pointer_offset_bits (op.type (), ns);
12171227
12181228 if (!op_width.has_value () || *op_width <= 0 )
12191229 return unchanged (expr);
12201230
1221- if (*start < offset && offset <= *end + *op_width)
1231+ // current value of offset is the index (within the concatenated
1232+ // expression) of the most-significant bit of op plus 1
1233+ if (*end >= offset)
1234+ {
1235+ // Operand is entirely below the extracted range.
1236+ // Adjust new_index to account for the removed operand.
1237+ new_index -= *op_width;
1238+ }
1239+ else if (offset - *op_width <= *start)
12221240 {
1223- extractbits_exprt result = expr;
1224- result.src () = op;
1225- result.index () =
1226- from_integer (*end - (offset - *op_width), expr.index ().type ());
1227- return changed (simplify_extractbits (result));
1241+ new_operands.push_back (op);
1242+ new_concat_width += *op_width;
12281243 }
12291244
12301245 offset -= *op_width;
12311246 }
1247+
1248+ if (new_operands.size () == 1 )
1249+ {
1250+ extractbits_exprt result = expr;
1251+ result.src () = new_operands.front ();
1252+ result.index () = from_integer (new_index, expr.index ().type ());
1253+ return changed (simplify_extractbits (result));
1254+ }
1255+ else if (
1256+ !new_operands.empty () &&
1257+ new_operands.size () < expr.src ().operands ().size ())
1258+ {
1259+ extractbits_exprt result = expr;
1260+ result.src ().operands () = new_operands;
1261+ to_bitvector_type (result.src ().type ())
1262+ .set_width (numeric_cast_v<std::size_t >(new_concat_width));
1263+ result.index () = from_integer (new_index, expr.index ().type ());
1264+ return changed (simplify_extractbits (result));
1265+ }
12321266 }
12331267 else if (auto eb_src = expr_try_dynamic_cast<extractbits_exprt>(expr.src ()))
12341268 {
@@ -1242,11 +1276,6 @@ simplify_exprt::simplify_extractbits(const extractbits_exprt &expr)
12421276 return changed (simplify_extractbits (result));
12431277 }
12441278 }
1245- else if (*end == 0 && *start + 1 == *width)
1246- {
1247- typecast_exprt tc{expr.src (), expr.type ()};
1248- return changed (simplify_typecast (tc));
1249- }
12501279
12511280 return unchanged (expr);
12521281}
0 commit comments