Skip to content

Commit afa6023

Browse files
authored
Merge pull request diffblue#2061 from tautschnig/simplify-extractbits
Simplify extractbits
2 parents 06b3adc + b663734 commit afa6023

File tree

3 files changed

+54
-23
lines changed

3 files changed

+54
-23
lines changed

src/util/simplify_expr.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2317,7 +2317,7 @@ bool simplify_exprt::simplify_node(exprt &expr)
23172317
else if(expr.id()==ID_concatenation)
23182318
result=simplify_concatenation(expr) && result;
23192319
else if(expr.id()==ID_extractbits)
2320-
result=simplify_extractbits(expr) && result;
2320+
result = simplify_extractbits(to_extractbits_expr(expr)) && result;
23212321
else if(expr.id()==ID_ieee_float_equal ||
23222322
expr.id()==ID_ieee_float_notequal)
23232323
result=simplify_ieee_float_relation(expr) && result;

src/util/simplify_expr_class.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class bswap_exprt;
2828
class byte_extract_exprt;
2929
class byte_update_exprt;
3030
class exprt;
31+
class extractbits_exprt;
3132
class if_exprt;
3233
class index_exprt;
3334
class member_exprt;
@@ -66,7 +67,7 @@ class simplify_exprt
6667

6768
bool simplify_typecast(exprt &expr);
6869
bool simplify_extractbit(exprt &expr);
69-
bool simplify_extractbits(exprt &expr);
70+
bool simplify_extractbits(extractbits_exprt &expr);
7071
bool simplify_concatenation(exprt &expr);
7172
bool simplify_mult(exprt &expr);
7273
bool simplify_div(exprt &expr);

src/util/simplify_expr_int.cpp

+51-21
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ Author: Daniel Kroening, [email protected]
1818
#include "expr_util.h"
1919
#include "fixedbv.h"
2020
#include "ieee_float.h"
21+
#include "invariant.h"
2122
#include "namespace.h"
23+
#include "pointer_offset_size.h"
2224
#include "rational.h"
2325
#include "rational_tools.h"
2426
#include "std_expr.h"
@@ -1101,48 +1103,76 @@ bool simplify_exprt::simplify_power(exprt &expr)
11011103
}
11021104

11031105
/// Simplifies extracting of bits from a constant.
1104-
bool simplify_exprt::simplify_extractbits(exprt &expr)
1106+
bool simplify_exprt::simplify_extractbits(extractbits_exprt &expr)
11051107
{
1106-
assert(expr.operands().size()==3);
1107-
1108-
const typet &op0_type=expr.op0().type();
1108+
const typet &op0_type = expr.src().type();
11091109

11101110
if(!is_bitvector_type(op0_type) &&
11111111
!is_bitvector_type(expr.type()))
11121112
return true;
11131113

1114-
if(expr.op0().is_constant())
1115-
{
1116-
std::size_t width=to_bitvector_type(op0_type).get_width();
1117-
mp_integer start, end;
1114+
mp_integer start, end;
11181115

1119-
if(to_integer(expr.op1(), start))
1120-
return true;
1116+
if(to_integer(expr.upper(), start))
1117+
return true;
11211118

1122-
if(to_integer(expr.op2(), end))
1123-
return true;
1119+
if(to_integer(expr.lower(), end))
1120+
return true;
11241121

1125-
if(start<0 || start>=width ||
1126-
end<0 || end>=width)
1127-
return true;
1122+
const mp_integer width = pointer_offset_bits(op0_type, ns);
1123+
1124+
if(start < 0 || start >= width || end < 0 || end >= width)
1125+
return true;
11281126

1129-
assert(start>=end); // is this always the case??
1127+
DATA_INVARIANT(
1128+
start >= end,
1129+
"extractbits must have upper() >= lower()");
11301130

1131-
const irep_idt &value=expr.op0().get(ID_value);
1131+
if(expr.src().is_constant())
1132+
{
1133+
const irep_idt &value = to_constant_expr(expr.src()).get_value();
11321134

11331135
if(value.size()!=width)
11341136
return true;
11351137

11361138
std::string svalue=id2string(value);
11371139

1138-
std::string extracted_value=
1139-
svalue.substr(width-integer2size_t(start)-1,
1140-
integer2size_t(start-end+1));
1140+
std::string extracted_value =
1141+
svalue.substr(
1142+
integer2size_t(width - start - 1),
1143+
integer2size_t(start - end + 1));
11411144

1142-
expr = constant_exprt(extracted_value, expr.type());
1145+
constant_exprt result(extracted_value, expr.type());
1146+
expr.swap(result);
11431147

11441148
return false;
11451149
}
1150+
else if(expr.src().id() == ID_concatenation)
1151+
{
1152+
// the most-significant bit comes first in an concatenation_exprt, hence we
1153+
// count down
1154+
mp_integer offset = width;
1155+
1156+
forall_operands(it, expr.src())
1157+
{
1158+
mp_integer op_width = pointer_offset_bits(it->type(), ns);
1159+
1160+
if(op_width <= 0)
1161+
return true;
1162+
1163+
if(start + 1 == offset && end + op_width == offset)
1164+
{
1165+
exprt tmp = *it;
1166+
if(tmp.type() != expr.type())
1167+
return true;
1168+
1169+
expr.swap(tmp);
1170+
return false;
1171+
}
1172+
1173+
offset -= op_width;
1174+
}
1175+
}
11461176

11471177
return true;
11481178
}

0 commit comments

Comments
 (0)