Skip to content

Commit 7501fca

Browse files
committed
Simplify (T1)(T2)x over integer bitvector types where T1 and x have the same type
When T2 has the same width (and also is an integer bitvector type) then the typecasts do not change the result -- we can use `x` directly.
1 parent c740a89 commit 7501fca

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-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 where T1, T2 are integer bitvector types (signedbv,
1370+
// unsignedbv, bv) of the same width and the type 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: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,3 +652,19 @@ TEST_CASE("Simplify quantifier", "[core][util]")
652652
REQUIRE(simplify_expr(forall_exprt{a, true_exprt{}}, ns) == true_exprt{});
653653
}
654654
}
655+
656+
TEST_CASE(
657+
"Simplify double typecast over integer bitvector types",
658+
"[core][util]")
659+
{
660+
const symbol_tablet symbol_table;
661+
const namespacet ns{symbol_table};
662+
663+
// (unsigned)(signed)x where x is unsigned and same width -> x
664+
const unsignedbv_typet u32{32};
665+
const signedbv_typet s32{32};
666+
const symbol_exprt x{"x", u32};
667+
const typecast_exprt inner{x, s32};
668+
const typecast_exprt outer{inner, u32};
669+
REQUIRE(simplify_expr(outer, ns) == x);
670+
}

0 commit comments

Comments
 (0)