Skip to content

Commit c1065e0

Browse files
author
Daniel Kroening
authored
Merge pull request #3199 from diffblue/bvirep-cleanup
bitvector representation cleanup
2 parents 4aa01f1 + e5850b8 commit c1065e0

File tree

7 files changed

+69
-33
lines changed

7 files changed

+69
-33
lines changed

src/solvers/flattening/boolbv_get.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ exprt boolbvt::bv_get_rec(
215215
}
216216
}
217217

218+
// most significant bit first
218219
std::string value;
219220

220221
for(std::size_t bit_nr=offset; bit_nr<offset+width; bit_nr++)
@@ -261,7 +262,11 @@ exprt boolbvt::bv_get_rec(
261262

262263
default:
263264
case bvtypet::IS_C_ENUM:
264-
return constant_exprt(value, type);
265+
{
266+
const irep_idt bvrep = make_bvrep(
267+
width, [&value](size_t i) { return value[value.size() - i - 1] == '1'; });
268+
return constant_exprt(bvrep, type);
269+
}
265270
}
266271

267272
return nil_exprt();

src/solvers/flattening/bv_pointers.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,11 @@ exprt bv_pointerst::bv_get_rec(
633633
// we treat these like bit-vector constants, but with
634634
// some additional annotation
635635

636-
constant_exprt result(value, type);
636+
const irep_idt bvrep = make_bvrep(bits, [&value](std::size_t i) {
637+
return value[value.size() - 1 - i] == '1';
638+
});
639+
640+
constant_exprt result(bvrep, type);
637641

638642
pointer_logict::pointert pointer;
639643
pointer.object=integer2size_t(binary2integer(value_addr, false));

src/solvers/lowering/popcount.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ exprt lower_popcount(const popcount_exprt &expr, const namespacet &ns)
4747
bitstring.reserve(new_width);
4848
for(std::size_t i = 0; i < new_width / (2 * shift); ++i)
4949
bitstring += std::string(shift, '0') + std::string(shift, '1');
50-
constant_exprt bitmask(bitstring, x.type());
50+
const mp_integer value = binary2integer(bitstring, false);
51+
constant_exprt bitmask(integer2bv(value, new_width), x.type());
5152
// build the expression
5253
x = plus_exprt(bitand_exprt(x, bitmask), bitand_exprt(shifted_x, bitmask));
5354
}

src/solvers/refinement/string_refinement.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,8 +1449,8 @@ static exprt sum_over_map(
14491449
int second=negated?(-term.second):term.second;
14501450
if(t.id()==ID_constant)
14511451
{
1452-
std::string value(to_constant_expr(t).get_value().c_str());
1453-
constants+=binary2integer(value, true)*second;
1452+
const auto int_value = numeric_cast_v<mp_integer>(to_constant_expr(t));
1453+
constants += int_value * second;
14541454
}
14551455
else
14561456
{

src/util/json_expr.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ json_objectt json(
217217
return result;
218218
}
219219

220+
static std::string binary(const constant_exprt &src)
221+
{
222+
const auto width = to_bitvector_type(src.type()).get_width();
223+
const auto int_val = bv2integer(id2string(src.get_value()), width, false);
224+
return integer2binary(int_val, width);
225+
}
226+
220227
/// Output a CBMC expression in json.
221228
/// The mode is used to correctly report types.
222229
/// \param expr: an expression
@@ -263,15 +270,15 @@ json_objectt json(
263270
std::size_t width=to_bitvector_type(type).get_width();
264271

265272
result["name"]=json_stringt("integer");
266-
result["binary"] = json_stringt(constant_expr.get_value());
273+
result["binary"] = json_stringt(binary(constant_expr));
267274
result["width"]=json_numbert(std::to_string(width));
268275
result["type"]=json_stringt(type_string);
269276
result["data"]=json_stringt(value_string);
270277
}
271278
else if(type.id()==ID_c_enum)
272279
{
273280
result["name"]=json_stringt("integer");
274-
result["binary"] = json_stringt(constant_expr.get_value());
281+
result["binary"] = json_stringt(binary(constant_expr));
275282
result["width"] =
276283
json_numbert(to_c_enum_type(type).subtype().get_string(ID_width));
277284
result["type"]=json_stringt("enum");
@@ -287,21 +294,21 @@ json_objectt json(
287294
else if(type.id()==ID_bv)
288295
{
289296
result["name"]=json_stringt("bitvector");
290-
result["binary"] = json_stringt(constant_expr.get_value());
297+
result["binary"] = json_stringt(binary(constant_expr));
291298
}
292299
else if(type.id()==ID_fixedbv)
293300
{
294301
result["name"]=json_stringt("fixed");
295302
result["width"]=json_numbert(type.get_string(ID_width));
296-
result["binary"] = json_stringt(constant_expr.get_value());
303+
result["binary"] = json_stringt(binary(constant_expr));
297304
result["data"]=
298305
json_stringt(fixedbvt(to_constant_expr(expr)).to_ansi_c_string());
299306
}
300307
else if(type.id()==ID_floatbv)
301308
{
302309
result["name"]=json_stringt("float");
303310
result["width"]=json_numbert(type.get_string(ID_width));
304-
result["binary"] = json_stringt(constant_expr.get_value());
311+
result["binary"] = json_stringt(binary(constant_expr));
305312
result["data"]=
306313
json_stringt(ieee_floatt(to_constant_expr(expr)).to_ansi_c_string());
307314
}

src/util/simplify_expr.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,9 @@ exprt simplify_exprt::bits2expr(
14581458
tmp[i]=bits[map.map_bit(i)];
14591459

14601460
std::reverse(tmp.begin(), tmp.end());
1461-
return constant_exprt(tmp, type);
1461+
1462+
mp_integer i = binary2integer(tmp, false);
1463+
return constant_exprt(integer2bv(i, bits.size()), type);
14621464
}
14631465
else if(type.id()==ID_c_enum)
14641466
{
@@ -1567,14 +1569,15 @@ optionalt<std::string> simplify_exprt::expr2bits(
15671569
type.id()==ID_floatbv ||
15681570
type.id()==ID_fixedbv)
15691571
{
1570-
std::string nat=id2string(to_constant_expr(expr).get_value());
1571-
std::reverse(nat.begin(), nat.end());
1572+
const auto width = to_bitvector_type(type).get_width();
1573+
const auto &bvrep = to_constant_expr(expr).get_value();
15721574

15731575
endianness_mapt map(type, little_endian, ns);
15741576

1575-
std::string result=nat;
1576-
for(std::string::size_type i=0; i<nat.size(); ++i)
1577-
result[map.map_bit(i)]=nat[i];
1577+
std::string result(width, ' ');
1578+
1579+
for(std::string::size_type i = 0; i < width; ++i)
1580+
result[map.map_bit(i)] = get_bitvector_bit(bvrep, width, i) ? '1' : '0';
15781581

15791582
return result;
15801583
}

src/util/simplify_expr_int.cpp

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -787,10 +787,12 @@ bool simplify_exprt::simplify_bitwise(exprt &expr)
787787
it!=expr.operands().end();
788788
) // no it++
789789
{
790-
if(it->is_constant() &&
791-
id2string(to_constant_expr(*it).get_value()).find('0')==
792-
std::string::npos &&
793-
expr.operands().size()>1)
790+
if(
791+
it->is_constant() &&
792+
bv2integer(
793+
id2string(to_constant_expr(*it).get_value()), width, false) ==
794+
power(2, width) - 1 &&
795+
expr.operands().size() > 1)
794796
{
795797
it=expr.operands().erase(it);
796798
result=false;
@@ -885,8 +887,9 @@ bool simplify_exprt::simplify_concatenation(exprt &expr)
885887
exprt &op=*it;
886888
if(op.is_true() || op.is_false())
887889
{
888-
bool value=op.is_true();
889-
op=constant_exprt(value?ID_1:ID_0, unsignedbv_typet(1));
890+
const bool value = op.is_true();
891+
op = from_integer(value, unsignedbv_typet(1));
892+
result = false;
890893
}
891894
}
892895

@@ -904,13 +907,24 @@ bool simplify_exprt::simplify_concatenation(exprt &expr)
904907
is_bitvector_type(opn.type()))
905908
{
906909
// merge!
907-
const std::string new_value=
908-
opi.get_string(ID_value)+opn.get_string(ID_value);
909-
opi.set(ID_value, new_value);
910-
opi.type().set(ID_width, new_value.size());
910+
const auto &value_i = to_constant_expr(opi).get_value();
911+
const auto &value_n = to_constant_expr(opn).get_value();
912+
const auto width_i = to_bitvector_type(opi.type()).get_width();
913+
const auto width_n = to_bitvector_type(opn.type()).get_width();
914+
const auto new_width = width_i + width_n;
915+
916+
const auto new_value = make_bvrep(
917+
new_width, [&value_i, &value_n, width_i, width_n](std::size_t x) {
918+
return x < width_n
919+
? get_bitvector_bit(value_n, width_n, x)
920+
: get_bitvector_bit(value_i, width_i, x - width_n);
921+
});
922+
923+
to_constant_expr(opi).set_value(new_value);
924+
opi.type().set(ID_width, new_width);
911925
// erase opn
912926
expr.operands().erase(expr.operands().begin()+i+1);
913-
result=true;
927+
result = false;
914928
}
915929
else
916930
i++;
@@ -941,7 +955,7 @@ bool simplify_exprt::simplify_concatenation(exprt &expr)
941955
opi.type().id(ID_verilog_unsignedbv);
942956
// erase opn
943957
expr.operands().erase(expr.operands().begin()+i+1);
944-
result=true;
958+
result = false;
945959
}
946960
else
947961
i++;
@@ -1269,13 +1283,15 @@ bool simplify_exprt::simplify_bitnot(exprt &expr)
12691283

12701284
exprt &op=operands.front();
12711285

1272-
if(expr.type().id()==ID_bv ||
1273-
expr.type().id()==ID_unsignedbv ||
1274-
expr.type().id()==ID_signedbv)
1286+
const auto &type = expr.type();
1287+
1288+
if(
1289+
type.id() == ID_bv || type.id() == ID_unsignedbv ||
1290+
type.id() == ID_signedbv)
12751291
{
1276-
const auto width = to_bitvector_type(expr.type()).get_width();
1292+
const auto width = to_bitvector_type(type).get_width();
12771293

1278-
if(op.type()==expr.type())
1294+
if(op.type() == type)
12791295
{
12801296
if(op.id()==ID_constant)
12811297
{

0 commit comments

Comments
 (0)