Skip to content

Commit db313e9

Browse files
committed
Implement multiplication overflow to smt terms conversion
1 parent 1ca9450 commit db313e9

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,40 @@ static smt_termt convert_expr_to_smt(const minus_overflow_exprt &minus_overflow)
908908

909909
static smt_termt convert_expr_to_smt(const mult_overflow_exprt &mult_overflow)
910910
{
911+
PRECONDITION(mult_overflow.lhs().type() == mult_overflow.rhs().type());
912+
const auto &operand_type = mult_overflow.lhs().type();
913+
const smt_termt left = convert_expr_to_smt(mult_overflow.lhs());
914+
const smt_termt right = convert_expr_to_smt(mult_overflow.rhs());
915+
if(
916+
const auto unsigned_type =
917+
type_try_dynamic_cast<unsignedbv_typet>(operand_type))
918+
{
919+
const std::size_t width = unsigned_type->get_width();
920+
const auto extend = smt_bit_vector_theoryt::zero_extend(width);
921+
return smt_bit_vector_theoryt::unsigned_greater_than_or_equal(
922+
smt_bit_vector_theoryt::multiply(extend(left), extend(right)),
923+
smt_bit_vector_constant_termt{power(2, width), width * 2});
924+
}
925+
if(
926+
const auto signed_type =
927+
type_try_dynamic_cast<signedbv_typet>(operand_type))
928+
{
929+
const smt_termt msb_left = most_significant_bit_is_set(left);
930+
const smt_termt msb_right = most_significant_bit_is_set(right);
931+
const std::size_t width = signed_type->get_width();
932+
const auto extend = smt_bit_vector_theoryt::sign_extend(width);
933+
const auto multiplication =
934+
smt_bit_vector_theoryt::multiply(extend(left), extend(right));
935+
const auto too_large = smt_bit_vector_theoryt::signed_greater_than_or_equal(
936+
multiplication,
937+
smt_bit_vector_constant_termt{power(2, width - 1), width * 2});
938+
const auto too_small = smt_bit_vector_theoryt::signed_less_than(
939+
multiplication,
940+
smt_bit_vector_theoryt::negate(
941+
smt_bit_vector_constant_termt{power(2, width - 1), width * 2}));
942+
return smt_core_theoryt::if_then_else(
943+
smt_core_theoryt::equal(msb_left, msb_right), too_large, too_small);
944+
}
911945
UNIMPLEMENTED_FEATURE(
912946
"Generation of SMT formula for multiply overflow expression: " +
913947
mult_overflow.pretty());

0 commit comments

Comments
 (0)