Skip to content

Commit f55f636

Browse files
authored
Merge pull request #8597 from diffblue/fixup-8538
fixup #8538 -- correct rounding modes for `floor`, `trunc`
2 parents 159af34 + 968c28f commit f55f636

File tree

22 files changed

+120
-45
lines changed

22 files changed

+120
-45
lines changed

regression/cbmc-library/floor-01/main.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
int main()
55
{
6-
floor();
7-
assert(0);
6+
assert(floor(1.1) == 1.0);
7+
assert(floor(1.9) == 1.0);
8+
assert(floor(-1.1) == -2.0);
9+
assert(floor(-1.9) == -2.0);
10+
assert(signbit(floor(-0.0)));
811
return 0;
912
}

regression/cbmc-library/floor-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/floorf-01/main.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
int main()
55
{
6-
floorf();
7-
assert(0);
6+
assert(floorf(1.1f) == 1.0f);
7+
assert(floorf(1.9f) == 1.0f);
8+
assert(floorf(-1.1f) == -2.0f);
9+
assert(floorf(-1.9f) == -2.0f);
10+
assert(signbit(floorf(-0.0f)));
811
return 0;
912
}

regression/cbmc-library/floorf-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/floorl-01/main.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33

44
int main()
55
{
6-
floorl();
7-
assert(0);
6+
assert(floorl(1.1l) == 1.0l);
7+
assert(floorl(1.9l) == 1.0l);
8+
assert(floorl(-1.1l) == -2.0l);
9+
assert(floorl(-1.9l) == -2.0l);
10+
11+
#if !defined(__APPLE__) || __ENVIRONMENT_OS_VERSION_MIN_REQUIRED__ >= 150000
12+
assert(signbit(floorl(-0.0l)));
13+
#endif
14+
815
return 0;
916
}

regression/cbmc-library/floorl-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/round-01/main.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33

44
int main()
55
{
6-
round();
7-
assert(0);
6+
assert(round(1.1) == 1.0);
7+
assert(round(1.5) == 2.0);
8+
assert(round(1.9) == 2.0);
9+
assert(round(-1.1) == -1.0);
10+
assert(round(-1.5) == -2.0);
11+
assert(round(-1.9) == -2.0);
12+
assert(signbit(round(-0.0)));
813
return 0;
914
}

regression/cbmc-library/round-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/roundf-01/main.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33

44
int main()
55
{
6-
roundf();
7-
assert(0);
6+
assert(roundf(1.1f) == 1.0f);
7+
assert(roundf(1.5f) == 2.0f);
8+
assert(roundf(1.9f) == 2.0f);
9+
assert(roundf(-1.1f) == -1.0f);
10+
assert(roundf(-1.5f) == -2.0f);
11+
assert(roundf(-1.9f) == -2.0f);
12+
assert(signbit(roundf(-0.0f)));
813
return 0;
914
}

regression/cbmc-library/roundf-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/roundl-01/main.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,16 @@
33

44
int main()
55
{
6-
roundl();
7-
assert(0);
6+
assert(roundl(1.1l) == 1.0l);
7+
assert(roundl(1.5l) == 2.0l);
8+
assert(roundl(1.9l) == 2.0l);
9+
assert(roundl(-1.1l) == -1.0l);
10+
assert(roundl(-1.5l) == -2.0l);
11+
assert(roundl(-1.9l) == -2.0l);
12+
13+
#if !defined(__APPLE__) || __ENVIRONMENT_OS_VERSION_MIN_REQUIRED__ >= 150000
14+
assert(signbit(roundl(-0.0l)));
15+
#endif
16+
817
return 0;
918
}

regression/cbmc-library/roundl-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/trunc-01/main.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
int main()
55
{
6-
trunc();
7-
assert(0);
6+
assert(trunc(1.1) == 1.0);
7+
assert(trunc(1.9) == 1.0);
8+
assert(trunc(-1.1) == -1.0);
9+
assert(trunc(-1.9) == -1.0);
10+
assert(signbit(trunc(-0.0)));
811
return 0;
912
}

regression/cbmc-library/trunc-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/truncf-01/main.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
int main()
55
{
6-
truncf();
7-
assert(0);
6+
assert(truncf(1.1f) == 1.0f);
7+
assert(truncf(1.9f) == 1.0f);
8+
assert(truncf(-1.1f) == -1.0f);
9+
assert(truncf(-1.9f) == -1.0f);
10+
assert(signbit(trunc(-0.0f)));
811
return 0;
912
}

regression/cbmc-library/truncf-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

regression/cbmc-library/truncl-01/main.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33

44
int main()
55
{
6-
truncl();
7-
assert(0);
6+
assert(truncl(1.1l) == 1.0l);
7+
assert(truncl(1.9l) == 1.0l);
8+
assert(truncl(-1.1l) == -1.0l);
9+
assert(truncl(-1.9l) == -1.0l);
10+
11+
#if !defined(__APPLE__) || __ENVIRONMENT_OS_VERSION_MIN_REQUIRED__ >= 150000
12+
assert(signbit(truncl(-0.0l)));
13+
#endif
14+
815
return 0;
916
}

regression/cbmc-library/truncl-01/test.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
KNOWNBUG
1+
CORE
22
main.c
3-
--pointer-check --bounds-check
3+
44
^EXIT=0$
55
^SIGNAL=0$
66
^VERIFICATION SUCCESSFUL$

src/ansi-c/library/math.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ long double ceill(long double x)
13221322

13231323
double floor(double x)
13241324
{
1325-
return __CPROVER_round_to_integrald(x, 3); // FE_DOWNWARD
1325+
return __CPROVER_round_to_integrald(x, 1); // FE_DOWNWARD
13261326
}
13271327

13281328
/* FUNCTION: floorf */
@@ -1339,7 +1339,7 @@ double floor(double x)
13391339

13401340
float floorf(float x)
13411341
{
1342-
return __CPROVER_round_to_integralf(x, 3); // FE_DOWNWARD
1342+
return __CPROVER_round_to_integralf(x, 1); // FE_DOWNWARD
13431343
}
13441344

13451345

@@ -1357,7 +1357,7 @@ float floorf(float x)
13571357

13581358
long double floorl(long double x)
13591359
{
1360-
return __CPROVER_round_to_integralld(x, 3); // FE_DOWNWARD
1360+
return __CPROVER_round_to_integralld(x, 1); // FE_DOWNWARD
13611361
}
13621362

13631363

@@ -1381,7 +1381,7 @@ long double floorl(long double x)
13811381

13821382
double trunc(double x)
13831383
{
1384-
return __CPROVER_round_to_integrald(x, 0); // FE_TOWARDZERO
1384+
return __CPROVER_round_to_integrald(x, 3); // FE_TOWARDZERO
13851385
}
13861386

13871387
/* FUNCTION: truncf */
@@ -1398,7 +1398,7 @@ double trunc(double x)
13981398

13991399
float truncf(float x)
14001400
{
1401-
return __CPROVER_round_to_integralf(x, 0); // FE_TOWARDZERO
1401+
return __CPROVER_round_to_integralf(x, 3); // FE_TOWARDZERO
14021402
}
14031403

14041404

@@ -1416,7 +1416,7 @@ float truncf(float x)
14161416

14171417
long double truncl(long double x)
14181418
{
1419-
return __CPROVER_round_to_integralld(x, 0); // FE_TOWARDZERO
1419+
return __CPROVER_round_to_integralld(x, 3); // FE_TOWARDZERO
14201420
}
14211421

14221422

@@ -1889,7 +1889,7 @@ long long int llroundl(long double x)
18891889

18901890
double modf(double x, double *iptr)
18911891
{
1892-
*iptr = __CPROVER_round_to_integrald(x, 0); // FE_TOWARDZERO
1892+
*iptr = __CPROVER_round_to_integrald(x, 3); // FE_TOWARDZERO
18931893
return (x - *iptr);
18941894
}
18951895

@@ -1907,7 +1907,7 @@ double modf(double x, double *iptr)
19071907

19081908
float modff(float x, float *iptr)
19091909
{
1910-
*iptr = __CPROVER_round_to_integralf(x, 0); // FE_TOWARDZERO
1910+
*iptr = __CPROVER_round_to_integralf(x, 3); // FE_TOWARDZERO
19111911
return (x - *iptr);
19121912
}
19131913

@@ -1926,7 +1926,7 @@ float modff(float x, float *iptr)
19261926

19271927
long double modfl(long double x, long double *iptr)
19281928
{
1929-
*iptr = __CPROVER_round_to_integralld(x, 0); // FE_TOWARDZERO
1929+
*iptr = __CPROVER_round_to_integralld(x, 3); // FE_TOWARDZERO
19301930
return (x - *iptr);
19311931
}
19321932

src/util/simplify_expr.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -2986,6 +2986,11 @@ simplify_exprt::resultt<> simplify_exprt::simplify_node(const exprt &node)
29862986
{
29872987
r = simplify_floatbv_op(to_ieee_float_op_expr(expr));
29882988
}
2989+
else if(expr.id() == ID_floatbv_round_to_integral)
2990+
{
2991+
r = simplify_floatbv_round_to_integral(
2992+
to_floatbv_round_to_integral_expr(expr));
2993+
}
29892994
else if(expr.id()==ID_floatbv_typecast)
29902995
{
29912996
r = simplify_floatbv_typecast(to_floatbv_typecast_expr(expr));

src/util/simplify_expr_class.h

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class exprt;
4545
class extractbit_exprt;
4646
class extractbits_exprt;
4747
class find_first_set_exprt;
48+
class floatbv_round_to_integral_exprt;
4849
class floatbv_typecast_exprt;
4950
class function_application_exprt;
5051
class ieee_float_op_exprt;
@@ -162,6 +163,8 @@ class simplify_exprt
162163
[[nodiscard]] resultt<> simplify_minus(const minus_exprt &);
163164
[[nodiscard]] resultt<> simplify_floatbv_op(const ieee_float_op_exprt &);
164165
[[nodiscard]] resultt<>
166+
simplify_floatbv_round_to_integral(const floatbv_round_to_integral_exprt &);
167+
[[nodiscard]] resultt<>
165168
simplify_floatbv_typecast(const floatbv_typecast_exprt &);
166169
[[nodiscard]] resultt<> simplify_shifts(const shift_exprt &);
167170
[[nodiscard]] resultt<> simplify_power(const power_exprt &);

src/util/simplify_expr_floatbv.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,28 @@ bool simplify_exprt::simplify_sign(exprt &expr)
135135
}
136136
#endif
137137

138+
simplify_exprt::resultt<> simplify_exprt::simplify_floatbv_round_to_integral(
139+
const floatbv_round_to_integral_exprt &expr)
140+
{
141+
auto &op = expr.op();
142+
auto &rounding_mode = expr.rounding_mode();
143+
144+
// constant folding
145+
if(op.is_constant() && rounding_mode.is_constant())
146+
{
147+
const auto rounding_mode_index =
148+
numeric_cast_v<std::size_t>(to_constant_expr(rounding_mode));
149+
150+
ieee_floatt op_value{
151+
to_constant_expr(op),
152+
static_cast<ieee_floatt::rounding_modet>(rounding_mode_index)};
153+
154+
return op_value.round_to_integral().to_expr();
155+
}
156+
157+
return unchanged(expr);
158+
}
159+
138160
simplify_exprt::resultt<>
139161
simplify_exprt::simplify_floatbv_typecast(const floatbv_typecast_exprt &expr)
140162
{

0 commit comments

Comments
 (0)