Skip to content

Commit

Permalink
Simplify typecast of zero-extension to just a typecast
Browse files Browse the repository at this point in the history
The intervening zero-extension does not alter the semantics and hinders
the application of `skip_typecast`.
  • Loading branch information
tautschnig committed Feb 9, 2025
1 parent 66004dc commit c975ed1
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
2 changes: 1 addition & 1 deletion regression/cbmc/Quantifiers-type2/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ int main()

// clang-format off
// clang-format would rewrite the "==>" as "== >"
__CPROVER_assume( __CPROVER_forall { char i; (i>=0 && i<2) ==> b[i]>=10 && b[i]<=10 } );
__CPROVER_assume( __CPROVER_forall { signed char i; (i>=0 && i<2) ==> b[i]>=10 && b[i]<=10 } );
__CPROVER_assume( __CPROVER_forall { unsigned i; (i>=0 && i<2) ==> c[i]>=10 && c[i]<=10 } );
// clang-format on

Expand Down
16 changes: 16 additions & 0 deletions regression/cbmc/Quantifiers-type2/unsigned-char.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
int main()
{
int b[2];
int c[2];

// clang-format off
// clang-format would rewrite the "==>" as "== >"
__CPROVER_assume( __CPROVER_forall { unsigned char i; (i>=0 && i<2) ==> b[i]>=10 && b[i]<=10 } );
__CPROVER_assume( __CPROVER_forall { unsigned i; (i>=0 && i<2) ==> c[i]>=10 && c[i]<=10 } );
// clang-format on

assert(b[0] == 10 && b[1] == 10);
assert(c[0] == 10 && c[1] == 10);

return 0;
}
11 changes: 11 additions & 0 deletions regression/cbmc/Quantifiers-type2/unsigned-char.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CORE no-new-smt
unsigned-char.c

^\*\* Results:$
^\[main.assertion.1\] line 12 assertion b\[.*0\] == 10 && b\[.*1\] == 10: SUCCESS$
^\[main.assertion.2\] line 13 assertion c\[.*0\] == 10 && c\[.*1\] == 10: SUCCESS$
^VERIFICATION SUCCESSFUL$
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
28 changes: 28 additions & 0 deletions src/util/simplify_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,34 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
else if(op_id==ID_ashr || op_id==ID_lshr || op_id==ID_shl)
{
}
else if(op_id == ID_zero_extend)
{
const exprt &zero_extended_op = to_zero_extend_expr(expr.op());
if(

Check warning on line 981 in src/util/simplify_expr.cpp

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L980-L981

Added lines #L980 - L981 were not covered by tests
auto bv_type =
type_try_dynamic_cast<bitvector_typet>(zero_extended_op.type()))
{
DATA_INVARIANT(
bv_type->get_width() <= to_bitvector_type(op_type).get_width(),

Check warning on line 986 in src/util/simplify_expr.cpp

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L983-L986

Added lines #L983 - L986 were not covered by tests
"zero extension must not reduce bit width");

auto new_expr = expr;
new_expr.op() = zero_extended_op;
return changed(simplify_typecast(new_expr)); // rec. call

Check warning on line 991 in src/util/simplify_expr.cpp

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L988-L991

Added lines #L988 - L991 were not covered by tests
}
}
else if(op_id == ID_concatenation)
{
const auto &operands = expr.op().operands();
if(
operands.size() == 2 && operands.front().is_constant() &&
to_constant_expr(operands.front()).value_is_zero_string())
{

Check warning on line 1000 in src/util/simplify_expr.cpp

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L1000

Added line #L1000 was not covered by tests
auto new_expr = expr;
new_expr.op() = operands.back();
return changed(simplify_typecast(new_expr)); // rec. call
}
}
}
}

Expand Down

0 comments on commit c975ed1

Please sign in to comment.