Skip to content

Commit 3e7bc8e

Browse files
authored
Merge pull request #3042 from hannes-steffenhagen-diffblue/feature-invariant_cleanup-flattening-floatbv_op
Invariant cleanup in flattening/boolbv_floatbv_op
2 parents 660772a + 1da5e18 commit 3e7bc8e

File tree

1 file changed

+52
-38
lines changed

1 file changed

+52
-38
lines changed

src/solvers/flattening/boolbv_floatbv_op.cpp

Lines changed: 52 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -79,82 +79,96 @@ bvt boolbvt::convert_floatbv_op(const exprt &expr)
7979
if(operands.size()!=3)
8080
throw "operator "+expr.id_string()+" takes three operands";
8181

82-
const exprt &op0=expr.op0(); // first operand
83-
const exprt &op1=expr.op1(); // second operand
84-
const exprt &op2=expr.op2(); // rounding mode
82+
const exprt &lhs = expr.op0();
83+
const exprt &rhs = expr.op1();
84+
const exprt &rounding_mode = expr.op2();
8585

86-
bvt bv0=convert_bv(op0);
87-
bvt bv1=convert_bv(op1);
88-
bvt bv2=convert_bv(op2);
86+
bvt lhs_as_bv = convert_bv(lhs);
87+
bvt rhs_as_bv = convert_bv(rhs);
88+
bvt rounding_mode_as_bv = convert_bv(rounding_mode);
8989

90-
const typet &type=ns.follow(expr.type());
91-
DATA_INVARIANT(
92-
op0.type() == type && op1.type() == type,
93-
"float op with mixed types:\n" + expr.pretty());
90+
const typet &resolved_type = ns.follow(expr.type());
91+
DATA_INVARIANT_WITH_DIAGNOSTICS(
92+
lhs.type() == resolved_type && rhs.type() == resolved_type,
93+
"both operands of a floating point operator must have the same type",
94+
irep_pretty_diagnosticst{expr});
9495

9596
float_utilst float_utils(prop);
9697

97-
float_utils.set_rounding_mode(bv2);
98+
float_utils.set_rounding_mode(rounding_mode_as_bv);
9899

99-
if(type.id()==ID_floatbv)
100+
if(resolved_type.id() == ID_floatbv)
100101
{
101102
float_utils.spec=ieee_float_spect(to_floatbv_type(expr.type()));
102103

103104
if(expr.id()==ID_floatbv_plus)
104-
return float_utils.add_sub(bv0, bv1, false);
105+
return float_utils.add_sub(lhs_as_bv, rhs_as_bv, false);
105106
else if(expr.id()==ID_floatbv_minus)
106-
return float_utils.add_sub(bv0, bv1, true);
107+
return float_utils.add_sub(lhs_as_bv, rhs_as_bv, true);
107108
else if(expr.id()==ID_floatbv_mult)
108-
return float_utils.mul(bv0, bv1);
109+
return float_utils.mul(lhs_as_bv, rhs_as_bv);
109110
else if(expr.id()==ID_floatbv_div)
110-
return float_utils.div(bv0, bv1);
111+
return float_utils.div(lhs_as_bv, rhs_as_bv);
111112
else if(expr.id()==ID_floatbv_rem)
112-
return float_utils.rem(bv0, bv1);
113+
return float_utils.rem(lhs_as_bv, rhs_as_bv);
113114
else
114-
throw "unexpected operator "+expr.id_string();
115+
UNREACHABLE;
115116
}
116-
else if(type.id()==ID_vector || type.id()==ID_complex)
117+
else if(resolved_type.id() == ID_vector || resolved_type.id() == ID_complex)
117118
{
118-
const typet &subtype=ns.follow(type.subtype());
119+
const typet &subtype = ns.follow(resolved_type.subtype());
119120

120121
if(subtype.id()==ID_floatbv)
121122
{
122123
float_utils.spec=ieee_float_spect(to_floatbv_type(subtype));
123124

124-
std::size_t width=boolbv_width(type);
125+
std::size_t width = boolbv_width(resolved_type);
125126
std::size_t sub_width=boolbv_width(subtype);
126127

127-
if(sub_width==0 || width%sub_width!=0)
128-
throw "convert_floatbv_op: unexpected vector operand width";
128+
DATA_INVARIANT(
129+
sub_width > 0 && width % sub_width == 0,
130+
"width of a vector subtype must be positive and evenly divide the "
131+
"width of the vector");
129132

130133
std::size_t size=width/sub_width;
131-
bvt bv;
132-
bv.resize(width);
134+
bvt result_bv;
135+
result_bv.resize(width);
133136

134137
for(std::size_t i=0; i<size; i++)
135138
{
136-
bvt tmp_bv0, tmp_bv1, tmp_bv;
139+
bvt lhs_sub_bv, rhs_sub_bv, sub_result_bv;
137140

138-
tmp_bv0.assign(bv0.begin()+i*sub_width, bv0.begin()+(i+1)*sub_width);
139-
tmp_bv1.assign(bv1.begin()+i*sub_width, bv1.begin()+(i+1)*sub_width);
141+
lhs_sub_bv.assign(
142+
lhs_as_bv.begin() + i * sub_width,
143+
lhs_as_bv.begin() + (i + 1) * sub_width);
144+
rhs_sub_bv.assign(
145+
rhs_as_bv.begin() + i * sub_width,
146+
rhs_as_bv.begin() + (i + 1) * sub_width);
140147

141148
if(expr.id()==ID_floatbv_plus)
142-
tmp_bv=float_utils.add_sub(tmp_bv0, tmp_bv1, false);
149+
sub_result_bv = float_utils.add_sub(lhs_sub_bv, rhs_sub_bv, false);
143150
else if(expr.id()==ID_floatbv_minus)
144-
tmp_bv=float_utils.add_sub(tmp_bv0, tmp_bv1, true);
151+
sub_result_bv = float_utils.add_sub(lhs_sub_bv, rhs_sub_bv, true);
145152
else if(expr.id()==ID_floatbv_mult)
146-
tmp_bv=float_utils.mul(tmp_bv0, tmp_bv1);
153+
sub_result_bv = float_utils.mul(lhs_sub_bv, rhs_sub_bv);
147154
else if(expr.id()==ID_floatbv_div)
148-
tmp_bv=float_utils.div(tmp_bv0, tmp_bv1);
155+
sub_result_bv = float_utils.div(lhs_sub_bv, rhs_sub_bv);
149156
else
150-
assert(false);
151-
152-
assert(tmp_bv.size()==sub_width);
153-
assert(i*sub_width+sub_width-1<bv.size());
154-
std::copy(tmp_bv.begin(), tmp_bv.end(), bv.begin()+i*sub_width);
157+
UNREACHABLE;
158+
159+
INVARIANT(
160+
sub_result_bv.size() == sub_width,
161+
"we constructed a new vector of the right size");
162+
INVARIANT(
163+
i * sub_width + sub_width - 1 < result_bv.size(),
164+
"the sub-bitvector fits into the result bitvector");
165+
std::copy(
166+
sub_result_bv.begin(),
167+
sub_result_bv.end(),
168+
result_bv.begin() + i * sub_width);
155169
}
156170

157-
return bv;
171+
return result_bv;
158172
}
159173
else
160174
return conversion_failed(expr);

0 commit comments

Comments
 (0)