Skip to content

Commit c0dd77e

Browse files
committed
introduce __CPROVER_remainder functions
This adds the __CPROVER_remainder family of functions, which are mapped to floatbv_rem.
1 parent 3824f29 commit c0dd77e

File tree

7 files changed

+81
-0
lines changed

7 files changed

+81
-0
lines changed

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2591,6 +2591,30 @@ exprt c_typecheck_baset::do_special_functions(
25912591

25922592
return std::move(fmod_expr);
25932593
}
2594+
else if(
2595+
identifier == CPROVER_PREFIX "remainder" ||
2596+
identifier == CPROVER_PREFIX "remainderf" ||
2597+
identifier == CPROVER_PREFIX "remainderl")
2598+
{
2599+
if(expr.arguments().size() != 2)
2600+
{
2601+
error().source_location = f_op.source_location();
2602+
error() << "remainder-functions expect two operands" << eom;
2603+
throw 0;
2604+
}
2605+
2606+
typecheck_function_call_arguments(expr);
2607+
2608+
// The semantics of these functions is meant to match the
2609+
// "floating point remainder" operation as defined by IEEE.
2610+
// Note that these do not take a rounding mode.
2611+
binary_exprt floatbv_rem_expr(
2612+
expr.arguments()[0], ID_floatbv_rem, expr.arguments()[1]);
2613+
2614+
floatbv_rem_expr.add_source_location() = source_location;
2615+
2616+
return std::move(floatbv_rem_expr);
2617+
}
25942618
else if(identifier==CPROVER_PREFIX "allocate")
25952619
{
25962620
if(expr.arguments().size()!=2)

src/ansi-c/cprover_builtin_headers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ float __CPROVER_fabsf(float x);
9090
double __CPROVER_fmod(double, double);
9191
float __CPROVER_fmodf(float, float);
9292
long double __CPROVER_fmodl(long double, long double);
93+
double __CPROVER_remainder(double, double);
94+
float __CPROVER_remainderf(float, float);
95+
long double __CPROVER_remainderl(long double, long double);
9396

9497
// arrays
9598
__CPROVER_bool __CPROVER_array_equal(const void *array1, const void *array2);

src/ansi-c/library/cprover.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ float __CPROVER_fabsf(float);
121121
double __CPROVER_fmod(double, double);
122122
float __CPROVER_fmodf(float, float);
123123
long double __CPROVER_fmodl(long double, long double);
124+
double __CPROVER_remainder(double, double);
125+
float __CPROVER_remainderf(float, float);
126+
long double __CPROVER_remainderl(long double, long double);
124127

125128
// arrays
126129
//__CPROVER_bool __CPROVER_array_equal(const void *array1, const void *array2);

src/solvers/flattening/boolbv.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ bvt boolbvt::convert_bitvector(const exprt &expr)
140140
}
141141
else if(expr.id() == ID_floatbv_mod)
142142
return convert_floatbv_mod_rem(to_binary_expr(expr));
143+
else if(expr.id() == ID_floatbv_rem)
144+
return convert_floatbv_mod_rem(to_binary_expr(expr));
143145
else if(expr.id()==ID_floatbv_typecast)
144146
return convert_floatbv_typecast(to_floatbv_typecast_expr(expr));
145147
else if(expr.id()==ID_concatenation)

src/solvers/smt2/smt2_conv.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,10 @@ void smt2_convt::convert_expr(const exprt &expr)
12931293
{
12941294
convert_floatbv_mult(to_ieee_float_op_expr(expr));
12951295
}
1296+
else if(expr.id() == ID_floatbv_rem)
1297+
{
1298+
convert_floatbv_rem(to_binary_expr(expr));
1299+
}
12961300
else if(expr.id()==ID_address_of)
12971301
{
12981302
const address_of_exprt &address_of_expr = to_address_of_expr(expr);
@@ -3631,6 +3635,29 @@ void smt2_convt::convert_floatbv_mult(const ieee_float_op_exprt &expr)
36313635
convert_floatbv(expr);
36323636
}
36333637

3638+
void smt2_convt::convert_floatbv_rem(const binary_exprt &expr)
3639+
{
3640+
DATA_INVARIANT(
3641+
expr.type().id() == ID_floatbv,
3642+
"type of ieee floating point expression shall be floatbv");
3643+
3644+
if(use_FPA_theory)
3645+
{
3646+
// Note that these do not have a rounding mode
3647+
out << "(fp.rem ";
3648+
convert_expr(expr.lhs());
3649+
out << " ";
3650+
convert_expr(expr.rhs());
3651+
out << ")";
3652+
}
3653+
else
3654+
{
3655+
SMT2_TODO(
3656+
"smt2_convt::convert_floatbv_rem to be implemented when not using "
3657+
"FPA_theory");
3658+
}
3659+
}
3660+
36343661
void smt2_convt::convert_with(const with_exprt &expr)
36353662
{
36363663
// get rid of "with" that has more than three operands

src/solvers/smt2/smt2_conv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class smt2_convt : public stack_decision_proceduret
119119
void convert_floatbv_minus(const ieee_float_op_exprt &expr);
120120
void convert_floatbv_div(const ieee_float_op_exprt &expr);
121121
void convert_floatbv_mult(const ieee_float_op_exprt &expr);
122+
void convert_floatbv_rem(const binary_exprt &expr);
122123
void convert_mod(const mod_exprt &expr);
123124
void convert_index(const index_exprt &expr);
124125
void convert_member(const member_exprt &expr);

src/solvers/smt2/smt2_parser.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,27 @@ void smt2_parsert::setup_expressions()
12171217
return function_application_ieee_float_op("fp.div", operands());
12181218
};
12191219

1220+
expressions["fp.rem"] = [this] {
1221+
auto op = operands();
1222+
1223+
// Note that these do not have a rounding mode.
1224+
if(op.size() != 2)
1225+
throw error() << "fp.rem takes three operands";
1226+
1227+
if(op[0].type().id() != ID_floatbv || op[1].type().id() != ID_floatbv)
1228+
throw error() << "fp.rem takes FloatingPoint operands";
1229+
1230+
if(op[0].type() != op[1].type())
1231+
{
1232+
throw error()
1233+
<< "fp.rem takes FloatingPoint operands with matching sort, "
1234+
<< "but got " << smt2_format(op[0].type()) << " vs "
1235+
<< smt2_format(op[1].type());
1236+
}
1237+
1238+
return binary_exprt(op[0], ID_floatbv_rem, op[1]);
1239+
};
1240+
12201241
expressions["fp.eq"] = [this] {
12211242
return function_application_ieee_float_eq(operands());
12221243
};

0 commit comments

Comments
 (0)