@@ -862,6 +862,33 @@ simplify_exprt::simplify_concatenation(const concatenation_exprt &expr)
862
862
new_expr.operands ().erase (new_expr.operands ().begin () + i + 1 );
863
863
no_change = false ;
864
864
}
865
+ else if (
866
+ skip_typecast (opi).id () == ID_extractbits &&
867
+ skip_typecast (opn).id () == ID_extractbits)
868
+ {
869
+ const extractbits_exprt &eb_i = to_extractbits_expr (skip_typecast (opi));
870
+ const extractbits_exprt &eb_n = to_extractbits_expr (skip_typecast (opn));
871
+
872
+ if (
873
+ eb_i.src () == eb_n.src () && eb_i.lower ().is_constant () &&
874
+ eb_n.upper ().is_constant () &&
875
+ numeric_cast_v<mp_integer>(to_constant_expr (eb_i.lower ())) ==
876
+ numeric_cast_v<mp_integer>(to_constant_expr (eb_n.upper ())) + 1 )
877
+ {
878
+ extractbits_exprt eb_merged = eb_i;
879
+ eb_merged.lower () = eb_n.lower ();
880
+ to_bitvector_type (eb_merged.type ())
881
+ .set_width (
882
+ to_bitvector_type (eb_i.type ()).get_width () +
883
+ to_bitvector_type (eb_n.type ()).get_width ());
884
+ opi = eb_merged;
885
+ // erase opn
886
+ new_expr.operands ().erase (new_expr.operands ().begin () + i + 1 );
887
+ no_change = false ;
888
+ }
889
+ else
890
+ ++i;
891
+ }
865
892
else
866
893
i++;
867
894
}
@@ -1100,18 +1127,38 @@ simplify_exprt::simplify_extractbits(const extractbits_exprt &expr)
1100
1127
if (!op_width.has_value () || *op_width <= 0 )
1101
1128
return unchanged (expr);
1102
1129
1103
- if (*start + 1 == offset && *end + *op_width == offset)
1130
+ if (*start < offset && *end >= offset - *op_width )
1104
1131
{
1105
- exprt tmp = *it;
1106
- if (tmp.type () != expr.type ())
1107
- return unchanged (expr);
1108
-
1109
- return std::move (tmp);
1132
+ extractbits_exprt result = expr;
1133
+ result.src () = *it;
1134
+ result.lower () =
1135
+ from_integer (*end - (offset - *op_width), expr.lower ().type ());
1136
+ result.upper () =
1137
+ from_integer (*start - (offset - *op_width), expr.upper ().type ());
1138
+ return changed (simplify_extractbits (result));
1110
1139
}
1111
1140
1112
1141
offset -= *op_width;
1113
1142
}
1114
1143
}
1144
+ else if (auto eb_src = expr_try_dynamic_cast<extractbits_exprt>(expr.src ()))
1145
+ {
1146
+ if (eb_src->upper ().is_constant () && eb_src->lower ().is_constant ())
1147
+ {
1148
+ extractbits_exprt result = *eb_src;
1149
+ result.type () = expr.type ();
1150
+ const mp_integer src_lower =
1151
+ numeric_cast_v<mp_integer>(to_constant_expr (eb_src->lower ()));
1152
+ result.lower () = from_integer (src_lower + *end, eb_src->lower ().type ());
1153
+ result.upper () = from_integer (src_lower + *start, eb_src->lower ().type ());
1154
+ return changed (simplify_extractbits (result));
1155
+ }
1156
+ }
1157
+ else if (*end == 0 && *start + 1 == *width)
1158
+ {
1159
+ typecast_exprt tc{expr.src (), expr.type ()};
1160
+ return changed (simplify_typecast (tc));
1161
+ }
1115
1162
1116
1163
return unchanged (expr);
1117
1164
}
0 commit comments