@@ -887,6 +887,33 @@ simplify_exprt::simplify_concatenation(const concatenation_exprt &expr)
887
887
new_expr.operands ().erase (new_expr.operands ().begin () + i + 1 );
888
888
no_change = false ;
889
889
}
890
+ else if (
891
+ skip_typecast (opi).id () == ID_extractbits &&
892
+ skip_typecast (opn).id () == ID_extractbits)
893
+ {
894
+ const extractbits_exprt &eb_i = to_extractbits_expr (skip_typecast (opi));
895
+ const extractbits_exprt &eb_n = to_extractbits_expr (skip_typecast (opn));
896
+
897
+ if (
898
+ eb_i.src () == eb_n.src () && eb_i.lower ().is_constant () &&
899
+ eb_n.upper ().is_constant () &&
900
+ numeric_cast_v<mp_integer>(to_constant_expr (eb_i.lower ())) ==
901
+ numeric_cast_v<mp_integer>(to_constant_expr (eb_n.upper ())) + 1 )
902
+ {
903
+ extractbits_exprt eb_merged = eb_i;
904
+ eb_merged.lower () = eb_n.lower ();
905
+ to_bitvector_type (eb_merged.type ())
906
+ .set_width (
907
+ to_bitvector_type (eb_i.type ()).get_width () +
908
+ to_bitvector_type (eb_n.type ()).get_width ());
909
+ opi = eb_merged;
910
+ // erase opn
911
+ new_expr.operands ().erase (new_expr.operands ().begin () + i + 1 );
912
+ no_change = false ;
913
+ }
914
+ else
915
+ ++i;
916
+ }
890
917
else
891
918
i++;
892
919
}
@@ -1125,18 +1152,38 @@ simplify_exprt::simplify_extractbits(const extractbits_exprt &expr)
1125
1152
if (!op_width.has_value () || *op_width <= 0 )
1126
1153
return unchanged (expr);
1127
1154
1128
- if (*start + 1 == offset && *end + *op_width == offset )
1155
+ if (*start < offset && offset <= *end + *op_width)
1129
1156
{
1130
- exprt tmp = *it;
1131
- if (tmp.type () != expr.type ())
1132
- return unchanged (expr);
1133
-
1134
- return std::move (tmp);
1157
+ extractbits_exprt result = expr;
1158
+ result.src () = *it;
1159
+ result.lower () =
1160
+ from_integer (*end - (offset - *op_width), expr.lower ().type ());
1161
+ result.upper () =
1162
+ from_integer (*start - (offset - *op_width), expr.upper ().type ());
1163
+ return changed (simplify_extractbits (result));
1135
1164
}
1136
1165
1137
1166
offset -= *op_width;
1138
1167
}
1139
1168
}
1169
+ else if (auto eb_src = expr_try_dynamic_cast<extractbits_exprt>(expr.src ()))
1170
+ {
1171
+ if (eb_src->upper ().is_constant () && eb_src->lower ().is_constant ())
1172
+ {
1173
+ extractbits_exprt result = *eb_src;
1174
+ result.type () = expr.type ();
1175
+ const mp_integer src_lower =
1176
+ numeric_cast_v<mp_integer>(to_constant_expr (eb_src->lower ()));
1177
+ result.lower () = from_integer (src_lower + *end, eb_src->lower ().type ());
1178
+ result.upper () = from_integer (src_lower + *start, eb_src->lower ().type ());
1179
+ return changed (simplify_extractbits (result));
1180
+ }
1181
+ }
1182
+ else if (*end == 0 && *start + 1 == *width)
1183
+ {
1184
+ typecast_exprt tc{expr.src (), expr.type ()};
1185
+ return changed (simplify_typecast (tc));
1186
+ }
1140
1187
1141
1188
return unchanged (expr);
1142
1189
}
0 commit comments