Skip to content

Commit 6475964

Browse files
committed
Simplify cond_exprt
This handles all the cases in the simplifier that special-cased if_exprt
1 parent e3a9157 commit 6475964

6 files changed

+205
-0
lines changed

src/util/simplify_expr.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,50 @@ bool simplify_exprt::simplify_if_preorder(if_exprt &expr)
12371237
return result;
12381238
}
12391239

1240+
bool simplify_exprt::simplify_cond_preorder(cond_exprt &expr)
1241+
{
1242+
cond_exprt new_expr({}, expr.type(), expr.is_exclusive());
1243+
bool result = true;
1244+
1245+
#ifdef USE_LOCAL_REPLACE_MAP
1246+
# error "TODO: implement simplify_cond_preorder use of replacement maps"
1247+
#endif
1248+
1249+
for(std::size_t i = 0; i < expr.get_n_cases(); ++i)
1250+
{
1251+
exprt condition = as_const(expr).condition(i);
1252+
if(!simplify_rec(condition))
1253+
result = false;
1254+
1255+
if(condition.is_true() && (i == 0 || expr.is_exclusive()))
1256+
{
1257+
expr.swap(expr.value(i));
1258+
simplify_rec(expr);
1259+
return false;
1260+
}
1261+
1262+
if(!condition.is_false())
1263+
{
1264+
exprt value = as_const(expr).value(i);
1265+
if(!simplify_rec(value))
1266+
result = false;
1267+
new_expr.add_case(condition, value);
1268+
}
1269+
else
1270+
{
1271+
result = false;
1272+
}
1273+
1274+
if(condition.is_true())
1275+
break;
1276+
}
1277+
1278+
if(!result)
1279+
expr = std::move(new_expr);
1280+
1281+
return result;
1282+
}
1283+
12401284
bool simplify_exprt::simplify_if(if_exprt &expr)
12411285
{
12421286
exprt &cond=expr.cond();
@@ -1343,6 +1387,27 @@ bool simplify_exprt::simplify_if(if_exprt &expr)
13431387
return result;
13441388
}
13451389

1390+
bool simplify_exprt::simplify_cond(cond_exprt &expr)
1391+
{
1392+
optionalt<exprt> unique_value;
1393+
for(std::size_t i = 0; i < expr.get_n_cases(); ++i)
1394+
{
1395+
const exprt &value = as_const(expr).value(i);
1396+
if(!unique_value.has_value())
1397+
unique_value = value;
1398+
else if(value != *unique_value)
1399+
return true;
1400+
}
1401+
1402+
if(unique_value.has_value())
1403+
{
1404+
expr.swap(*unique_value);
1405+
return false;
1406+
}
1407+
1408+
return true;
1409+
}
1410+
13461411
bool simplify_exprt::get_values(
13471412
const exprt &expr,
13481413
value_listt &value_list)
@@ -1365,6 +1430,14 @@ bool simplify_exprt::get_values(
13651430
return get_values(expr.op1(), value_list) ||
13661431
get_values(expr.operands().back(), value_list);
13671432
}
1433+
else if(expr.id() == ID_cond)
1434+
{
1435+
bool ret = false;
1436+
const auto &cond = to_cond_expr(expr);
1437+
for(std::size_t i = 0; i < cond.get_n_cases(); ++i)
1438+
ret |= get_values(cond.value(i), value_list);
1439+
return ret;
1440+
}
13681441

13691442
return true;
13701443
}
@@ -1877,6 +1950,13 @@ bool simplify_exprt::simplify_byte_extract(byte_extract_exprt &expr)
18771950
expr.swap(if_expr);
18781951
return false;
18791952
}
1953+
else if(expr.op().id() == ID_cond)
1954+
{
1955+
cond_exprt cond_expr = lift_cond(expr, 0);
1956+
for(std::size_t i = 0; i < cond_expr.get_n_cases(); ++i)
1957+
simplify_byte_extract(to_byte_extract_expr(cond_expr.value(i)));
1958+
simplify_cond(cond_expr);
1959+
}
18801960

18811961
const auto el_size = pointer_offset_bits(expr.type(), ns);
18821962

@@ -2387,6 +2467,8 @@ bool simplify_exprt::simplify_node_preorder(exprt &expr)
23872467
}
23882468
else if(expr.id()==ID_if)
23892469
result=simplify_if_preorder(to_if_expr(expr));
2470+
else if(expr.id() == ID_cond)
2471+
result = simplify_cond_preorder(to_cond_expr(expr));
23902472
else
23912473
{
23922474
if(expr.has_operands())
@@ -2423,6 +2505,8 @@ bool simplify_exprt::simplify_node(exprt &expr)
24232505
result=simplify_inequality(expr) && result;
24242506
else if(expr.id()==ID_if)
24252507
result=simplify_if(to_if_expr(expr)) && result;
2508+
else if(expr.id() == ID_cond)
2509+
result = simplify_cond(to_cond_expr(expr)) && result;
24262510
else if(expr.id()==ID_lambda)
24272511
result=simplify_lambda(expr) && result;
24282512
else if(expr.id()==ID_with)

src/util/simplify_expr_array.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,13 @@ bool simplify_exprt::simplify_index(exprt &expr)
219219

220220
return false;
221221
}
222+
else if(array.id() == ID_cond)
223+
{
224+
expr = lift_cond(expr, 0);
225+
simplify_rec(expr);
226+
227+
return false;
228+
}
222229

223230
return result;
224231
}

src/util/simplify_expr_class.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Author: Daniel Kroening, [email protected]
2727
class bswap_exprt;
2828
class byte_extract_exprt;
2929
class byte_update_exprt;
30+
class cond_exprt;
3031
class exprt;
3132
class extractbits_exprt;
3233
class if_exprt;
@@ -81,6 +82,8 @@ class simplify_exprt
8182
bool simplify_bitwise(exprt &expr);
8283
bool simplify_if_preorder(if_exprt &expr);
8384
bool simplify_if(if_exprt &expr);
85+
bool simplify_cond_preorder(cond_exprt &expr);
86+
bool simplify_cond(cond_exprt &expr);
8487
bool simplify_bitnot(exprt &expr);
8588
bool simplify_not(exprt &expr);
8689
bool simplify_boolean(exprt &expr);

src/util/simplify_expr_int.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,15 @@ bool simplify_exprt::simplify_inequality(exprt &expr)
13191319
return simplify_inequality(expr);
13201320
}
13211321

1322+
// if rhs is ID_cond (and lhs is not), swap operands for == and !=
1323+
if(
1324+
(expr.id() == ID_equal || expr.id() == ID_notequal) &&
1325+
tmp0.id() != ID_cond && tmp1.id() == ID_cond)
1326+
{
1327+
expr.op0().swap(expr.op1());
1328+
return simplify_inequality(expr);
1329+
}
1330+
13221331
if(tmp0.id()==ID_if && tmp0.operands().size()==3)
13231332
{
13241333
if_exprt if_expr=lift_if(expr, 0);
@@ -1330,6 +1339,17 @@ bool simplify_exprt::simplify_inequality(exprt &expr)
13301339
return false;
13311340
}
13321341

1342+
if(tmp0.id() == ID_cond)
1343+
{
1344+
cond_exprt cond_expr = lift_cond(expr, 0);
1345+
for(std::size_t i = 0; i < cond_expr.get_n_cases(); ++i)
1346+
simplify_inequality(cond_expr.value(i));
1347+
simplify_cond(cond_expr);
1348+
expr.swap(cond_expr);
1349+
1350+
return false;
1351+
}
1352+
13331353
// see if we are comparing pointers that are address_of
13341354
if((tmp0.id()==ID_address_of ||
13351355
(tmp0.id()==ID_typecast && tmp0.op0().id()==ID_address_of)) &&
@@ -1687,6 +1707,17 @@ bool simplify_exprt::simplify_inequality_constant(exprt &expr)
16871707
return false;
16881708
}
16891709

1710+
if(expr.op0().id() == ID_cond)
1711+
{
1712+
cond_exprt cond_expr = lift_cond(expr, 0);
1713+
for(std::size_t i = 0; i < cond_expr.get_n_cases(); ++i)
1714+
simplify_inequality_constant(cond_expr.value(i));
1715+
simplify_cond(cond_expr);
1716+
expr.swap(cond_expr);
1717+
1718+
return false;
1719+
}
1720+
16901721
// do we deal with pointers?
16911722
if(expr.op1().type().id()==ID_pointer)
16921723
{

src/util/simplify_expr_pointer.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,49 @@ bool simplify_exprt::simplify_address_of_arg(exprt &expr)
171171
return result;
172172
}
173173
}
174+
else if(expr.id() == ID_cond)
175+
{
176+
bool result = true;
177+
const auto &cond_expr = to_cond_expr(expr);
178+
cond_exprt new_cond_expr({}, cond_expr.type(), cond_expr.is_exclusive());
179+
180+
for(std::size_t i = 0; i < cond_expr.get_n_cases(); ++i)
181+
{
182+
exprt condition = cond_expr.condition(i);
183+
exprt value = cond_expr.value(i);
184+
185+
if(!simplify_rec(condition))
186+
result = false;
187+
188+
if(condition.is_false())
189+
continue;
190+
191+
if(!simplify_address_of_arg(value))
192+
result = false;
193+
194+
if(condition.is_true() && (cond_expr.is_exclusive() || i == 0))
195+
{
196+
expr.swap(value);
197+
return false;
198+
}
199+
200+
new_cond_expr.add_case(condition, value);
201+
202+
if(condition.is_true())
203+
break;
204+
}
205+
206+
if(new_cond_expr.get_n_cases() == 1)
207+
{
208+
expr = new_cond_expr.value(0);
209+
return false;
210+
}
211+
212+
if(!result)
213+
expr = std::move(new_cond_expr);
214+
215+
return result;
216+
}
174217

175218
return true;
176219
}
@@ -230,6 +273,16 @@ bool simplify_exprt::simplify_pointer_offset(exprt &expr)
230273

231274
return false;
232275
}
276+
else if(ptr.id() == ID_cond)
277+
{
278+
cond_exprt cond_expr = lift_cond(expr, 0);
279+
for(std::size_t i = 0; i < cond_expr.get_n_cases(); ++i)
280+
simplify_pointer_offset(cond_expr.value(i));
281+
simplify_cond(cond_expr);
282+
expr.swap(cond_expr);
283+
284+
return false;
285+
}
233286

234287
if(ptr.type().id()!=ID_pointer)
235288
return true;
@@ -506,6 +559,16 @@ bool simplify_exprt::simplify_pointer_object(exprt &expr)
506559

507560
return false;
508561
}
562+
else if(op.id() == ID_cond)
563+
{
564+
cond_exprt cond_expr = lift_cond(expr, 0);
565+
for(std::size_t i = 0; i < cond_expr.get_n_cases(); ++i)
566+
simplify_pointer_object(cond_expr.value(i));
567+
simplify_cond(cond_expr);
568+
expr.swap(cond_expr);
569+
570+
return false;
571+
}
509572

510573
return result;
511574
}
@@ -527,6 +590,16 @@ bool simplify_exprt::simplify_is_dynamic_object(exprt &expr)
527590

528591
return false;
529592
}
593+
else if(op.id() == ID_cond)
594+
{
595+
cond_exprt cond_expr = lift_cond(expr, 0);
596+
for(std::size_t i = 0; i < cond_expr.get_n_cases(); ++i)
597+
simplify_is_dynamic_object(cond_expr.value(i));
598+
simplify_cond(cond_expr);
599+
expr.swap(cond_expr);
600+
601+
return false;
602+
}
530603

531604
bool result=true;
532605

src/util/simplify_expr_struct.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,13 @@ bool simplify_exprt::simplify_member(exprt &expr)
282282

283283
return false;
284284
}
285+
else if(op.id() == ID_cond)
286+
{
287+
expr = lift_cond(expr, 0);
288+
simplify_rec(expr);
289+
290+
return false;
291+
}
285292

286293
return true;
287294
}

0 commit comments

Comments
 (0)