Skip to content

Commit bf450b6

Browse files
committed
Simplify (T1)(T2)x over bv types where T1 and x have the same type
When T2 has the same width (and also is a bitvector type) then the typecasts do not change the result -- we can use `x` directly.
1 parent 6df204e commit bf450b6

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

regression/contracts/no_redudant_checks/test.desc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ main.c
2323
^\[main.pointer_arithmetic.15\].*: SUCCESS
2424
^\[main.pointer_arithmetic.16\].*: SUCCESS
2525
^\[main.pointer_arithmetic.17\].*: SUCCESS
26-
^\[main.pointer_arithmetic.18\].*: SUCCESS
27-
^\*\* 0 of 21 failed \(1 iterations\)
26+
^\*\* 0 of 20 failed \(1 iterations\)
2827
^VERIFICATION SUCCESSFUL$
2928
--
3029
^\[main.overflow.\d+\].*: FAILURE
@@ -33,10 +32,10 @@ Checks that assertions generated by the first --pointer-overflow-check:
3332
- do not get duplicated by the second --unsigned-overflow-check
3433
- do not get instrumented with --unsigned-overflow-check (would fail the proof)
3534

36-
We expect 20 assertions to be generated:
35+
We expect 19 assertions to be generated:
3736
In the goto-instrument run:
3837
- 2 for using malloc
39-
- 18 caused by --pointer-overflow-check
38+
- 17 caused by --pointer-overflow-check
4039

4140
In the final cbmc run:
4241
- 0 caused by --pointer-overflow-check

src/util/simplify_expr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,20 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
13661366
// might enable further simplification
13671367
return changed(simplify_typecast(new_expr)); // recursive call
13681368
}
1369+
// (T1)(T2)x over bv types where T1 and T2 have the same width and the type
1370+
// of x is T1 --> x
1371+
const exprt &inner_op = to_typecast_expr(operand).op();
1372+
if(
1373+
inner_op.type() == expr_type &&
1374+
(expr_type_id == ID_unsignedbv || expr_type_id == ID_signedbv ||
1375+
expr_type_id == ID_bv) &&
1376+
(op_type_id == ID_unsignedbv || op_type_id == ID_signedbv ||
1377+
op_type_id == ID_bv) &&
1378+
to_bitvector_type(expr_type).get_width() ==
1379+
to_bitvector_type(operand.type()).get_width())
1380+
{
1381+
return inner_op;
1382+
}
13691383
}
13701384
else if(operand.id()==ID_address_of)
13711385
{

unit/util/simplify_expr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,3 +652,17 @@ TEST_CASE("Simplify quantifier", "[core][util]")
652652
REQUIRE(simplify_expr(forall_exprt{a, true_exprt{}}, ns) == true_exprt{});
653653
}
654654
}
655+
656+
TEST_CASE("Simplify double typecast over bv types", "[core][util]")
657+
{
658+
const symbol_tablet symbol_table;
659+
const namespacet ns{symbol_table};
660+
661+
// (unsigned)(signed)x where x is unsigned and same width -> x
662+
const unsignedbv_typet u32{32};
663+
const signedbv_typet s32{32};
664+
const symbol_exprt x{"x", u32};
665+
const typecast_exprt inner{x, s32};
666+
const typecast_exprt outer{inner, u32};
667+
REQUIRE(simplify_expr(outer, ns) == x);
668+
}

0 commit comments

Comments
 (0)