Skip to content

Simplify typecast of zero-extension to just a typecast #8586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
46 changes: 46 additions & 0 deletions src/util/simplify_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,52 @@
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()))
{
auto new_expr = expr;

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

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L983-L985

Added lines #L983 - L985 were not covered by tests
if(
bv_type->id() == ID_signedbv &&
bv_type->get_width() < to_bitvector_type(expr_type).get_width())
{
new_expr.op() =
simplify_typecast(
typecast_exprt{
zero_extended_op, unsignedbv_typet{bv_type->get_width()}})
.expr;

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

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L987-L994

Added lines #L987 - L994 were not covered by tests
}
else
new_expr.op() = zero_extended_op;
return changed(simplify_typecast(new_expr)); // rec. call

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

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L996-L998

Added lines #L996 - L998 were not covered by tests
}
}
else if(op_id == ID_concatenation)
{

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

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L1002

Added line #L1002 was not covered by tests
const auto &operands = expr.op().operands();
if(
operands.size() == 2 && operands.front().is_constant() &&
to_constant_expr(operands.front()).value_is_zero_string())
{
auto new_expr = expr;
const bitvector_typet &bv_type =
to_bitvector_type(operands.back().type());
if(bv_type.id() == ID_signedbv)
{
new_expr.op() =
simplify_typecast(
typecast_exprt{
operands.back(), unsignedbv_typet{bv_type.get_width()}})
.expr;

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

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L1012-L1017

Added lines #L1012 - L1017 were not covered by tests
}
else

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

View check run for this annotation

Codecov / codecov/patch

src/util/simplify_expr.cpp#L1019

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

Expand Down
Loading