13
13
#include " ieee_float.h"
14
14
#include " invariant.h"
15
15
#include " namespace.h"
16
+ #include " simplify_expr.h"
16
17
#include " std_expr.h"
17
18
18
19
bool simplify_exprt::simplify_isinf (exprt &expr)
@@ -141,43 +142,43 @@ bool simplify_exprt::simplify_floatbv_typecast(exprt &expr)
141
142
{
142
143
// These casts usually reduce precision, and thus, usually round.
143
144
144
- assert (expr. operands (). size ()== 2 );
145
+ auto const &floatbv_typecast_expr = to_floatbv_typecast_expr (expr);
145
146
146
- const typet &dest_type= ns.follow (expr .type ());
147
- const typet &src_type= ns.follow (expr. op0 ().type ());
147
+ const typet &dest_type = ns.follow (floatbv_typecast_expr .type ());
148
+ const typet &src_type = ns.follow (floatbv_typecast_expr. op ().type ());
148
149
149
150
// eliminate redundant casts
150
151
if (dest_type==src_type)
151
152
{
152
- expr=expr. op0 ();
153
+ expr = floatbv_typecast_expr. op ();
153
154
return false ;
154
155
}
155
156
156
- exprt op0=expr. op0 ();
157
- exprt op1=expr. op1 (); // rounding mode
157
+ const exprt &casted_expr = floatbv_typecast_expr. op ();
158
+ const exprt &rounding_mode = floatbv_typecast_expr. rounding_mode ();
158
159
159
160
// We can soundly re-write (float)((double)x op (double)y)
160
161
// to x op y. True for any rounding mode!
161
162
162
163
#if 0
163
- if(op0 .id()==ID_floatbv_div ||
164
- op0 .id()==ID_floatbv_mult ||
165
- op0 .id()==ID_floatbv_plus ||
166
- op0 .id()==ID_floatbv_minus)
164
+ if(casted_expr .id()==ID_floatbv_div ||
165
+ casted_expr .id()==ID_floatbv_mult ||
166
+ casted_expr .id()==ID_floatbv_plus ||
167
+ casted_expr .id()==ID_floatbv_minus)
167
168
{
168
- if(op0 .operands().size()==3 &&
169
- op0 .op0().id()==ID_typecast &&
170
- op0 .op1().id()==ID_typecast &&
171
- op0 .op0().operands().size()==1 &&
172
- op0 .op1().operands().size()==1 &&
173
- ns.follow(op0 .op0().type())==dest_type &&
174
- ns.follow(op0 .op1().type())==dest_type)
169
+ if(casted_expr .operands().size()==3 &&
170
+ casted_expr .op0().id()==ID_typecast &&
171
+ casted_expr .op1().id()==ID_typecast &&
172
+ casted_expr .op0().operands().size()==1 &&
173
+ casted_expr .op1().operands().size()==1 &&
174
+ ns.follow(casted_expr .op0().type())==dest_type &&
175
+ ns.follow(casted_expr .op1().type())==dest_type)
175
176
{
176
- exprt result(op0 .id(), expr .type());
177
+ exprt result(casted_expr .id(), floatbv_typecast_expr .type());
177
178
result.operands().resize(3);
178
- result.op0()=op0 .op0().op0();
179
- result.op1()=op0 .op1().op0();
180
- result.op2()=op1 ;
179
+ result.op0()=casted_expr .op0().op0();
180
+ result.op1()=casted_expr .op1().op0();
181
+ result.op2()=rounding_mode ;
181
182
182
183
simplify_node(result);
183
184
expr.swap(result);
@@ -187,18 +188,18 @@ bool simplify_exprt::simplify_floatbv_typecast(exprt &expr)
187
188
#endif
188
189
189
190
// constant folding
190
- if (op0 .is_constant () && op1 .is_constant ())
191
+ if (casted_expr .is_constant () && rounding_mode .is_constant ())
191
192
{
192
- mp_integer rounding_mode ;
193
- if (!to_integer (op1, rounding_mode ))
193
+ mp_integer rounding_mode_index ;
194
+ if (!to_integer (rounding_mode, rounding_mode_index ))
194
195
{
195
196
if (src_type.id ()==ID_floatbv)
196
197
{
197
198
if (dest_type.id ()==ID_floatbv) // float to float
198
199
{
199
- ieee_floatt result (to_constant_expr (op0 ));
200
- result.rounding_mode =
201
- (ieee_floatt::rounding_modet)integer2size_t (rounding_mode );
200
+ ieee_floatt result (to_constant_expr (casted_expr ));
201
+ result.rounding_mode =
202
+ (ieee_floatt::rounding_modet)integer2size_t (rounding_mode_index );
202
203
result.change_spec (
203
204
ieee_float_spect (to_floatbv_type (dest_type)));
204
205
expr=result.to_expr ();
@@ -207,11 +208,11 @@ bool simplify_exprt::simplify_floatbv_typecast(exprt &expr)
207
208
else if (dest_type.id ()==ID_signedbv ||
208
209
dest_type.id ()==ID_unsignedbv)
209
210
{
210
- if (rounding_mode== ieee_floatt::ROUND_TO_ZERO)
211
+ if (rounding_mode_index == ieee_floatt::ROUND_TO_ZERO)
211
212
{
212
- ieee_floatt result (to_constant_expr (op0 ));
213
- result.rounding_mode =
214
- (ieee_floatt::rounding_modet)integer2size_t (rounding_mode );
213
+ ieee_floatt result (to_constant_expr (casted_expr ));
214
+ result.rounding_mode =
215
+ (ieee_floatt::rounding_modet)integer2size_t (rounding_mode_index );
215
216
mp_integer value=result.to_integer ();
216
217
expr=from_integer (value, dest_type);
217
218
return false ;
@@ -222,13 +223,13 @@ bool simplify_exprt::simplify_floatbv_typecast(exprt &expr)
222
223
src_type.id ()==ID_unsignedbv)
223
224
{
224
225
mp_integer value;
225
- if (!to_integer (op0 , value))
226
+ if (!to_integer (casted_expr , value))
226
227
{
227
228
if (dest_type.id ()==ID_floatbv) // int to float
228
229
{
229
230
ieee_floatt result (to_floatbv_type (dest_type));
230
- result.rounding_mode =
231
- (ieee_floatt::rounding_modet)integer2size_t (rounding_mode );
231
+ result.rounding_mode =
232
+ (ieee_floatt::rounding_modet)integer2size_t (rounding_mode_index );
232
233
result.from_integer (value);
233
234
expr=result.to_expr ();
234
235
return false ;
@@ -239,15 +240,16 @@ bool simplify_exprt::simplify_floatbv_typecast(exprt &expr)
239
240
{
240
241
// go through underlying type
241
242
const auto &enum_type = ns.follow_tag (to_c_enum_tag_type (src_type));
242
- typecast_exprt tmp1 (op0, to_c_enum_type (enum_type). subtype ());
243
- simplify_typecast (tmp1 );
244
- if (tmp1 .is_constant ())
243
+ exprt simplified_typecast = simplify_expr (
244
+ typecast_exprt (casted_expr, to_c_enum_type (enum_type). subtype ()), ns );
245
+ if (simplified_typecast .is_constant ())
245
246
{
246
- exprt tmp2 = expr;
247
- tmp2.op0 () = tmp1;
248
- if (!simplify_floatbv_typecast (tmp2))
247
+ floatbv_typecast_exprt new_floatbv_typecast_expr =
248
+ floatbv_typecast_expr;
249
+ new_floatbv_typecast_expr.op () = simplified_typecast;
250
+ if (!simplify_floatbv_typecast (new_floatbv_typecast_expr))
249
251
{
250
- expr = tmp2 ;
252
+ expr = new_floatbv_typecast_expr ;
251
253
return false ;
252
254
}
253
255
}
@@ -257,23 +259,17 @@ bool simplify_exprt::simplify_floatbv_typecast(exprt &expr)
257
259
258
260
#if 0
259
261
// (T)(a?b:c) --> a?(T)b:(T)c
260
- if(expr.op0().id()==ID_if &&
261
- expr.op0().operands().size()==3)
262
+ if(casted_expr.id()==ID_if)
262
263
{
263
- binary_exprt tmp_op1(
264
- expr.op0().op1(),
265
- ID_floatbv_typecast,
266
- expr.op1(),
267
- dest_type);
268
- binary_exprt tmp_op2(
269
- expr.op0().op2(),
270
- ID_floatbv_typecast,
271
- expr.op1(),
272
- dest_type);
273
- simplify_floatbv_typecast(tmp_op1);
274
- simplify_floatbv_typecast(tmp_op2);
275
- expr=if_exprt(expr.op0().op0(), tmp_op1, tmp_op2, dest_type);
276
- simplify_if(expr);
264
+ auto const &casted_if_expr = to_if_expr(casted_expr);
265
+
266
+ floatbv_typecast_exprt casted_true_case(casted_if_expr.true_case(), rounding_mode, dest_type);
267
+ floatbv_typecast_exprt casted_false_case(casted_if_expr.false_case(), rounding_mode, dest_type);
268
+
269
+ simplify_floatbv_typecast(casted_true_case);
270
+ simplify_floatbv_typecast(casted_false_case);
271
+ auto simplified_if_expr = simplify_expr(if_exprt(casted_if_expr.cond(), casted_true_case, casted_false_case, dest_type), ns);
272
+ expr = simplified_if_expr;
277
273
return false;
278
274
}
279
275
#endif
0 commit comments