Skip to content

Commit 15eb581

Browse files
Merge pull request #6752 from thomasspriggs/tas/refactor_convert_overflow
Refactor `boolbvt::convert_overflow`
2 parents eff3bfc + fad0e20 commit 15eb581

File tree

3 files changed

+50
-49
lines changed

3 files changed

+50
-49
lines changed

src/solvers/flattening/boolbv.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,16 @@ literalt boolbvt::convert_rest(const exprt &expr)
417417
else if(expr.id()==ID_onehot || expr.id()==ID_onehot0)
418418
return convert_onehot(to_unary_expr(expr));
419419
else if(
420-
can_cast_expr<binary_overflow_exprt>(expr) ||
421-
can_cast_expr<unary_minus_overflow_exprt>(expr))
420+
const auto binary_overflow =
421+
expr_try_dynamic_cast<binary_overflow_exprt>(expr))
422422
{
423-
return convert_overflow(expr);
423+
return convert_binary_overflow(*binary_overflow);
424+
}
425+
else if(
426+
const auto unary_overflow =
427+
expr_try_dynamic_cast<unary_overflow_exprt>(expr))
428+
{
429+
return convert_unary_overflow(*unary_overflow);
424430
}
425431
else if(expr.id()==ID_isnan)
426432
{

src/solvers/flattening/boolbv.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Author: Daniel Kroening, [email protected]
2727
#include "arrays.h"
2828

2929
class array_comprehension_exprt;
30+
class binary_overflow_exprt;
3031
class bitreverse_exprt;
3132
class bswap_exprt;
3233
class byte_extract_exprt;
@@ -38,6 +39,7 @@ class floatbv_typecast_exprt;
3839
class ieee_float_op_exprt;
3940
class member_exprt;
4041
class replication_exprt;
42+
class unary_overflow_exprt;
4143
class union_typet;
4244

4345
class boolbvt:public arrayst
@@ -140,7 +142,8 @@ class boolbvt:public arrayst
140142
virtual literalt convert_reduction(const unary_exprt &expr);
141143
virtual literalt convert_onehot(const unary_exprt &expr);
142144
virtual literalt convert_extractbit(const extractbit_exprt &expr);
143-
virtual literalt convert_overflow(const exprt &expr);
145+
virtual literalt convert_binary_overflow(const binary_overflow_exprt &expr);
146+
virtual literalt convert_unary_overflow(const unary_overflow_exprt &expr);
144147
virtual literalt convert_equality(const equal_exprt &expr);
145148
virtual literalt convert_verilog_case_equality(
146149
const binary_relation_exprt &expr);

src/solvers/flattening/boolbv_overflow.cpp

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,55 +7,49 @@ Author: Daniel Kroening, [email protected]
77
\*******************************************************************/
88

99
#include <util/bitvector_expr.h>
10+
#include <util/bitvector_types.h>
1011
#include <util/invariant.h>
1112

1213
#include "boolbv.h"
1314

14-
literalt boolbvt::convert_overflow(const exprt &expr)
15+
literalt boolbvt::convert_binary_overflow(const binary_overflow_exprt &expr)
1516
{
16-
const auto plus_or_minus_conversion =
17-
[&](
18-
const binary_overflow_exprt &overflow_expr,
19-
const std::function<literalt(
20-
bv_utilst *, const bvt &, const bvt &, bv_utilst::representationt)>
21-
&bv_util_overflow) {
22-
const bvt &bv0 = convert_bv(overflow_expr.lhs());
23-
const bvt &bv1 = convert_bv(overflow_expr.rhs());
24-
25-
if(bv0.size() != bv1.size())
26-
return SUB::convert_rest(expr);
27-
28-
bv_utilst::representationt rep =
29-
overflow_expr.lhs().type().id() == ID_signedbv
30-
? bv_utilst::representationt::SIGNED
31-
: bv_utilst::representationt::UNSIGNED;
32-
33-
return bv_util_overflow(&bv_utils, bv0, bv1, rep);
34-
};
17+
const bvt &bv0 = convert_bv(expr.lhs());
18+
const bvt &bv1 = convert_bv(
19+
expr.rhs(),
20+
can_cast_expr<mult_overflow_exprt>(expr)
21+
? optionalt<std::size_t>{bv0.size()}
22+
: nullopt);
23+
24+
const bv_utilst::representationt rep =
25+
can_cast_type<signedbv_typet>(expr.lhs().type())
26+
? bv_utilst::representationt::SIGNED
27+
: bv_utilst::representationt::UNSIGNED;
28+
3529
if(
3630
const auto plus_overflow = expr_try_dynamic_cast<plus_overflow_exprt>(expr))
3731
{
38-
return plus_or_minus_conversion(*plus_overflow, &bv_utilst::overflow_add);
32+
if(bv0.size() != bv1.size())
33+
return SUB::convert_rest(expr);
34+
35+
return bv_utils.overflow_add(bv0, bv1, rep);
3936
}
4037
if(const auto minus = expr_try_dynamic_cast<minus_overflow_exprt>(expr))
4138
{
42-
return plus_or_minus_conversion(*minus, &bv_utilst::overflow_sub);
39+
if(bv0.size() != bv1.size())
40+
return SUB::convert_rest(expr);
41+
42+
return bv_utils.overflow_sub(bv0, bv1, rep);
4343
}
4444
else if(
4545
const auto mult_overflow = expr_try_dynamic_cast<mult_overflow_exprt>(expr))
4646
{
4747
if(
48-
mult_overflow->lhs().type().id() != ID_unsignedbv &&
49-
mult_overflow->lhs().type().id() != ID_signedbv)
48+
!can_cast_type<unsignedbv_typet>(expr.lhs().type()) &&
49+
!can_cast_type<signedbv_typet>(expr.lhs().type()))
50+
{
5051
return SUB::convert_rest(expr);
51-
52-
bvt bv0 = convert_bv(mult_overflow->lhs());
53-
bvt bv1 = convert_bv(mult_overflow->rhs(), bv0.size());
54-
55-
bv_utilst::representationt rep =
56-
mult_overflow->lhs().type().id() == ID_signedbv
57-
? bv_utilst::representationt::SIGNED
58-
: bv_utilst::representationt::UNSIGNED;
52+
}
5953

6054
DATA_INVARIANT(
6155
mult_overflow->lhs().type() == mult_overflow->rhs().type(),
@@ -65,10 +59,10 @@ literalt boolbvt::convert_overflow(const exprt &expr)
6559
std::size_t new_size=old_size*2;
6660

6761
// sign/zero extension
68-
bv0=bv_utils.extension(bv0, new_size, rep);
69-
bv1=bv_utils.extension(bv1, new_size, rep);
62+
const bvt &bv0_extended = bv_utils.extension(bv0, new_size, rep);
63+
const bvt &bv1_extended = bv_utils.extension(bv1, new_size, rep);
7064

71-
bvt result=bv_utils.multiplier(bv0, bv1, rep);
65+
bvt result = bv_utils.multiplier(bv0_extended, bv1_extended, rep);
7266

7367
if(rep==bv_utilst::representationt::UNSIGNED)
7468
{
@@ -100,23 +94,15 @@ literalt boolbvt::convert_overflow(const exprt &expr)
10094
else if(
10195
const auto shl_overflow = expr_try_dynamic_cast<shl_overflow_exprt>(expr))
10296
{
103-
const bvt &bv0 = convert_bv(shl_overflow->lhs());
104-
const bvt &bv1 = convert_bv(shl_overflow->rhs());
105-
10697
std::size_t old_size = bv0.size();
10798
std::size_t new_size = old_size * 2;
10899

109-
bv_utilst::representationt rep =
110-
shl_overflow->lhs().type().id() == ID_signedbv
111-
? bv_utilst::representationt::SIGNED
112-
: bv_utilst::representationt::UNSIGNED;
113-
114100
bvt bv_ext=bv_utils.extension(bv0, new_size, rep);
115101

116102
bvt result=bv_utils.shift(bv_ext, bv_utilst::shiftt::SHIFT_LEFT, bv1);
117103

118104
// a negative shift is undefined; yet this isn't an overflow
119-
literalt neg_shift = shl_overflow->lhs().type().id() == ID_unsignedbv
105+
literalt neg_shift = rep == bv_utilst::representationt::UNSIGNED
120106
? const_literal(false)
121107
: bv1.back(); // sign bit
122108

@@ -161,7 +147,13 @@ literalt boolbvt::convert_overflow(const exprt &expr)
161147
return
162148
prop.land(!neg_shift, prop.lselect(undef, prop.lor(bv0), overflow));
163149
}
164-
else if(
150+
151+
return SUB::convert_rest(expr);
152+
}
153+
154+
literalt boolbvt::convert_unary_overflow(const unary_overflow_exprt &expr)
155+
{
156+
if(
165157
const auto unary_minus_overflow =
166158
expr_try_dynamic_cast<unary_minus_overflow_exprt>(expr))
167159
{

0 commit comments

Comments
 (0)