File tree Expand file tree Collapse file tree 7 files changed +81
-0
lines changed
Expand file tree Collapse file tree 7 files changed +81
-0
lines changed Original file line number Diff line number Diff 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 )
Original file line number Diff line number Diff line change @@ -90,6 +90,9 @@ float __CPROVER_fabsf(float x);
9090double __CPROVER_fmod (double , double );
9191float __CPROVER_fmodf (float , float );
9292long 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 );
Original file line number Diff line number Diff line change @@ -121,6 +121,9 @@ float __CPROVER_fabsf(float);
121121double __CPROVER_fmod (double , double );
122122float __CPROVER_fmodf (float , float );
123123long 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);
Original file line number Diff line number Diff 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)
Original file line number Diff line number Diff 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+
36343661void smt2_convt::convert_with (const with_exprt &expr)
36353662{
36363663 // get rid of "with" that has more than three operands
Original file line number Diff line number Diff 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);
Original file line number Diff line number Diff 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 };
You can’t perform that action at this time.
0 commit comments