Skip to content

Commit 6dad1e8

Browse files
Merge pull request diffblue#284 from diffblue/fp-constant-folding-cherry-pick
FP constant folding fix cherry pick
2 parents f45635c + 9bf813d commit 6dad1e8

File tree

5 files changed

+72
-28
lines changed

5 files changed

+72
-28
lines changed

regression/cbmc/switch7/main.c

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// These need to be constant-folded at compile time
2+
3+
#define C1 (int)(0. / 1. + 0.5)
4+
#define C2 (int)(1. / 1. + 0.5)
5+
6+
int nondet_int();
7+
8+
int main(void)
9+
{
10+
int i = nondet_int();
11+
12+
switch(i)
13+
{
14+
case C1:
15+
break;
16+
17+
case C2:
18+
break;
19+
20+
default:
21+
break;
22+
}
23+
}

regression/cbmc/switch7/test.desc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/ansi-c/c_typecheck_expr.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Author: Daniel Kroening, [email protected]
2626
#include <util/simplify_expr.h>
2727
#include <util/string_constant.h>
2828

29+
#include <goto-programs/adjust_float_expressions.h>
30+
2931
#include "builtin_factory.h"
3032
#include "c_typecast.h"
3133
#include "c_qualifiers.h"
@@ -3451,6 +3453,13 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
34513453

34523454
void c_typecheck_baset::make_constant(exprt &expr)
34533455
{
3456+
// Floating-point expressions may require a rounding mode.
3457+
// ISO 9899:1999 F.7.2 says that the default is "round to nearest".
3458+
// Some compilers have command-line options to override.
3459+
const auto rounding_mode =
3460+
from_integer(ieee_floatt::ROUND_TO_EVEN, signed_int_type());
3461+
adjust_float_expressions(expr, rounding_mode);
3462+
34543463
simplify(expr, *this);
34553464

34563465
if(!expr.is_constant() &&

src/goto-programs/adjust_float_expressions.cpp

+30-28
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ Author: Daniel Kroening, [email protected]
2020

2121
#include "goto_model.h"
2222

23-
static bool have_to_adjust_float_expressions(
24-
const exprt &expr,
25-
const namespacet &ns)
23+
static bool have_to_adjust_float_expressions(const exprt &expr)
2624
{
2725
if(expr.id()==ID_floatbv_plus ||
2826
expr.id()==ID_floatbv_minus ||
@@ -33,11 +31,11 @@ static bool have_to_adjust_float_expressions(
3331
expr.id()==ID_floatbv_typecast)
3432
return false;
3533

36-
const typet &type=ns.follow(expr.type());
34+
const typet &type = expr.type();
3735

38-
if(type.id()==ID_floatbv ||
39-
(type.id()==ID_complex &&
40-
ns.follow(type.subtype()).id()==ID_floatbv))
36+
if(
37+
type.id() == ID_floatbv ||
38+
(type.id() == ID_complex && type.subtype().id() == ID_floatbv))
4139
{
4240
if(expr.id()==ID_plus || expr.id()==ID_minus ||
4341
expr.id()==ID_mult || expr.id()==ID_div ||
@@ -69,35 +67,29 @@ static bool have_to_adjust_float_expressions(
6967
}
7068

7169
forall_operands(it, expr)
72-
if(have_to_adjust_float_expressions(*it, ns))
70+
if(have_to_adjust_float_expressions(*it))
7371
return true;
7472

7573
return false;
7674
}
7775

7876
/// This adds the rounding mode to floating-point operations, including those in
7977
/// vectors and complex numbers.
80-
void adjust_float_expressions(
81-
exprt &expr,
82-
const namespacet &ns)
78+
void adjust_float_expressions(exprt &expr, const exprt &rounding_mode)
8379
{
84-
if(!have_to_adjust_float_expressions(expr, ns))
80+
if(!have_to_adjust_float_expressions(expr))
8581
return;
8682

87-
Forall_operands(it, expr)
88-
adjust_float_expressions(*it, ns);
83+
// recursive call
84+
for(auto &op : expr.operands())
85+
adjust_float_expressions(op, rounding_mode);
8986

90-
const typet &type=ns.follow(expr.type());
87+
const typet &type = expr.type();
9188

92-
if(type.id()==ID_floatbv ||
93-
(type.id()==ID_complex &&
94-
ns.follow(type.subtype()).id()==ID_floatbv))
89+
if(
90+
type.id() == ID_floatbv ||
91+
(type.id() == ID_complex && type.subtype().id() == ID_floatbv))
9592
{
96-
symbol_exprt rounding_mode=
97-
ns.lookup(CPROVER_PREFIX "rounding_mode").symbol_expr();
98-
99-
rounding_mode.add_source_location()=expr.source_location();
100-
10193
if(expr.id()==ID_plus || expr.id()==ID_minus ||
10294
expr.id()==ID_mult || expr.id()==ID_div ||
10395
expr.id()==ID_rem)
@@ -128,11 +120,6 @@ void adjust_float_expressions(
128120
const typet &src_type=typecast_expr.op().type();
129121
const typet &dest_type=typecast_expr.type();
130122

131-
symbol_exprt rounding_mode=
132-
ns.lookup(CPROVER_PREFIX "rounding_mode").symbol_expr();
133-
134-
rounding_mode.add_source_location()=expr.source_location();
135-
136123
if(dest_type.id()==ID_floatbv &&
137124
src_type.id()==ID_floatbv)
138125
{
@@ -179,6 +166,21 @@ void adjust_float_expressions(
179166
}
180167
}
181168

169+
/// This adds the rounding mode to floating-point operations, including those in
170+
/// vectors and complex numbers.
171+
void adjust_float_expressions(exprt &expr, const namespacet &ns)
172+
{
173+
if(!have_to_adjust_float_expressions(expr))
174+
return;
175+
176+
symbol_exprt rounding_mode =
177+
ns.lookup(CPROVER_PREFIX "rounding_mode").symbol_expr();
178+
179+
rounding_mode.add_source_location() = expr.source_location();
180+
181+
adjust_float_expressions(expr, rounding_mode);
182+
}
183+
182184
void adjust_float_expressions(
183185
goto_functionst::goto_functiont &goto_function,
184186
const namespacet &ns)

src/goto-programs/adjust_float_expressions.h

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ void adjust_float_expressions(
2222
exprt &expr,
2323
const namespacet &ns);
2424

25+
void adjust_float_expressions(exprt &expr, const exprt &rounding_mode);
26+
2527
void adjust_float_expressions(
2628
goto_functionst::goto_functiont &goto_function,
2729
const namespacet &ns);

0 commit comments

Comments
 (0)