Skip to content

Commit dbffea7

Browse files
author
Daniel Kroening
committed
simplifier: eliminate casts from bool to number
This usually enables subsequent simplification, e.g., ((int)B) != 0 turns into (B?1:0) != 0 and then into B?1!=0:0!=0 and then into B?true:false which then turns into B
1 parent 1edf4d9 commit dbffea7

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

jbmc/unit/util/simplify_expr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ void test_unnecessary_cast(const typet &type)
4747
REQUIRE(simplified.type()==java_int_type());
4848
}
4949

50+
// casts from boolean get rewritten to ?:
51+
if(type == java_boolean_type())
52+
{
53+
const exprt simplified = simplify_expr(
54+
typecast_exprt(symbol_exprt("foo", java_int_type()), type),
55+
namespacet(symbol_tablet()));
56+
57+
REQUIRE(simplified.id() == ID_if);
58+
REQUIRE(simplified.type() == type);
59+
}
60+
else
5061
{
5162
const exprt simplified=simplify_expr(
5263
typecast_exprt(symbol_exprt("foo", java_int_type()), type),

src/util/simplify_expr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,19 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
576576
return std::move(inequality);
577577
}
578578

579+
// eliminate casts from proper bool
580+
if(
581+
op_type.id() == ID_bool &&
582+
(expr_type.id() == ID_signedbv || expr_type.id() == ID_unsignedbv ||
583+
expr_type.id() == ID_c_bool || expr_type.id() == ID_c_bit_field))
584+
{
585+
// rewrite (T)(bool) to bool?1:0
586+
auto one = from_integer(1, expr_type);
587+
auto zero = from_integer(0, expr_type);
588+
exprt new_expr = if_exprt(expr.op(), std::move(one), std::move(zero));
589+
return changed(simplify_rec(new_expr)); // recursive call
590+
}
591+
579592
// circular casts through types shorter than `int`
580593
if(op_type == signedbv_typet(32) && expr.op().id() == ID_typecast)
581594
{

unit/util/simplify_expr.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,18 @@ TEST_CASE("Simplify pointer_object equality", "[core][util]")
244244

245245
REQUIRE(simp.is_true());
246246
}
247+
248+
TEST_CASE("Simplify cast from bool", "[core][util]")
249+
{
250+
symbol_tablet symbol_table;
251+
namespacet ns(symbol_table);
252+
253+
// this checks that ((int)B)==1 turns into B
254+
exprt B = symbol_exprt("B", bool_typet());
255+
exprt comparison = equal_exprt(
256+
typecast_exprt(B, signedbv_typet(32)), from_integer(1, signedbv_typet(32)));
257+
258+
exprt simp = simplify_expr(comparison, ns);
259+
260+
REQUIRE(simp == B);
261+
}

0 commit comments

Comments
 (0)