@@ -1122,78 +1122,69 @@ void fpa2bv_converter::mk_rem(sort * s, expr_ref & x, expr_ref & y, expr_ref & r
1122
1122
a_lz_ext = m_bv_util.mk_zero_extend (2 , a_lz);
1123
1123
b_lz_ext = m_bv_util.mk_zero_extend (2 , b_lz);
1124
1124
1125
- expr_ref exp_diff (m), neg_exp_diff (m), exp_diff_is_neg (m), exp_diff_ge_zero (m);
1125
+ expr_ref exp_diff (m), neg_exp_diff (m), exp_diff_is_neg (m), exp_diff_ge_zero (m), exp_diff_is_zero (m) ;
1126
1126
exp_diff = m_bv_util.mk_bv_sub (
1127
1127
m_bv_util.mk_bv_sub (a_exp_ext, a_lz_ext),
1128
1128
m_bv_util.mk_bv_sub (b_exp_ext, b_lz_ext));
1129
1129
neg_exp_diff = m_bv_util.mk_bv_neg (exp_diff);
1130
1130
exp_diff_is_neg = m_bv_util.mk_sle (exp_diff, m_bv_util.mk_numeral (0 , ebits+2 ));
1131
+ exp_diff_is_zero = m.mk_eq (exp_diff, m_bv_util.mk_numeral (0 , ebits+2 ));
1131
1132
exp_diff_ge_zero = m_bv_util.mk_sle (m_bv_util.mk_numeral (0 , m_bv_util.get_bv_size (exp_diff)), exp_diff);
1132
1133
dbg_decouple (" fpa2bv_rem_exp_diff" , exp_diff);
1133
1134
1134
1135
// CMW: This creates _huge_ bit-vectors, which is potentially sub-optimal,
1135
1136
// but calculating this via rem = x - y * nearest(x/y) creates huge
1136
1137
// circuits, too. Lazy instantiation seems the way to go in the long run
1137
1138
// (using the lazy bit-blaster helps on simple instances).
1138
- expr_ref a_sig_ext (m), b_sig_ext (m), lshift (m), rshift (m), shifted (m), huge_rem (m);
1139
+ expr_ref a_sig_ext (m), b_sig_ext (m), lshift (m), rshift (m), shifted (m), huge_rem (m), huge_div (m), huge_div_is_even (m) ;
1139
1140
a_sig_ext = m_bv_util.mk_concat (m_bv_util.mk_zero_extend (max_exp_diff_ui, a_sig), m_bv_util.mk_numeral (0 , 3 ));
1140
1141
b_sig_ext = m_bv_util.mk_concat (m_bv_util.mk_zero_extend (max_exp_diff_ui, b_sig), m_bv_util.mk_numeral (0 , 3 ));
1141
1142
lshift = m_bv_util.mk_zero_extend (max_exp_diff_ui + sbits - (ebits+2 ) + 3 , exp_diff);
1142
1143
rshift = m_bv_util.mk_zero_extend (max_exp_diff_ui + sbits - (ebits+2 ) + 3 , neg_exp_diff);
1143
1144
shifted = m.mk_ite (exp_diff_is_neg, m_bv_util.mk_bv_ashr (a_sig_ext, rshift),
1144
1145
m_bv_util.mk_bv_shl (a_sig_ext, lshift));
1145
1146
huge_rem = m_bv_util.mk_bv_urem (shifted, b_sig_ext);
1147
+ huge_div = m.mk_app (m_bv_util.get_fid (), OP_BUDIV_I, shifted, b_sig_ext);
1148
+ huge_div_is_even = m.mk_eq (m_bv_util.mk_extract (0 , 0 , huge_div), m_bv_util.mk_numeral (0 , 1 ));
1149
+ dbg_decouple (" fpa2bv_rem_exp_diff_is_neg" , exp_diff_is_neg);
1150
+ dbg_decouple (" fpa2bv_rem_lshift" , lshift);
1151
+ dbg_decouple (" fpa2bv_rem_rshift" , rshift);
1146
1152
dbg_decouple (" fpa2bv_rem_huge_rem" , huge_rem);
1153
+ dbg_decouple (" fpa2bv_rem_huge_div" , huge_div);
1147
1154
1148
- expr_ref rndd_sgn (m), rndd_exp (m), rndd_sig (m), rne_bv (m), rndd (m);
1155
+ expr_ref rndd_sgn (m), rndd_exp (m), rndd_sig (m), rne_bv (m), rndd_sig_lz (m);
1149
1156
rndd_sgn = a_sgn;
1150
1157
rndd_exp = m_bv_util.mk_bv_sub (b_exp_ext, b_lz_ext);
1151
1158
rndd_sig = m_bv_util.mk_extract (sbits+3 , 0 , huge_rem);
1152
1159
rne_bv = m_bv_util.mk_numeral (BV_RM_TIES_TO_EVEN, 3 );
1153
- round (s, rne_bv, rndd_sgn, rndd_sig, rndd_exp, rndd);
1154
-
1155
- expr_ref y_half (m), ny_half (m), zero_e (m), two_e (m);
1156
- expr_ref y_half_is_zero (m), y_half_is_nz (m);
1157
- expr_ref r_ge_y_half (m), r_gt_ny_half (m), r_le_y_half (m), r_lt_ny_half (m);
1158
- expr_ref r_ge_zero (m), r_le_zero (m);
1159
- expr_ref rounded_sub_y (m), rounded_add_y (m);
1160
- mpf zero, two;
1161
- m_mpf_manager.set (two, ebits, sbits, 2 );
1162
- m_mpf_manager.set (zero, ebits, sbits, 0 );
1163
- mk_numeral (s, two, two_e);
1164
- mk_numeral (s, zero, zero_e);
1165
- mk_div (s, rne_bv, y, two_e, y_half);
1166
- mk_neg (s, y_half, ny_half);
1167
- mk_is_zero (y_half, y_half_is_zero);
1168
- y_half_is_nz = m.mk_not (y_half_is_zero);
1169
-
1170
- mk_float_ge (s, rndd, y_half, r_ge_y_half);
1171
- mk_float_gt (s, rndd, ny_half, r_gt_ny_half);
1172
- mk_float_le (s, rndd, y_half, r_le_y_half);
1173
- mk_float_lt (s, rndd, ny_half, r_lt_ny_half);
1174
-
1175
- mk_sub (s, rne_bv, rndd, y, rounded_sub_y);
1176
- mk_add (s, rne_bv, rndd, y, rounded_add_y);
1177
-
1178
- expr_ref sub_cnd (m), add_cnd (m);
1179
- sub_cnd = m.mk_and (exp_diff_ge_zero,
1180
- m.mk_and (y_half_is_nz,
1181
- m.mk_or (m.mk_and (y_is_pos, r_ge_y_half),
1182
- m.mk_and (y_is_neg, r_le_y_half))));
1183
- add_cnd = m.mk_and (exp_diff_ge_zero,
1184
- m.mk_and (y_half_is_nz,
1185
- m.mk_or (m.mk_and (y_is_pos, r_lt_ny_half),
1186
- m.mk_and (y_is_neg, r_gt_ny_half))));
1187
-
1188
- dbg_decouple (" fpa2bv_rem_y_half" , y_half);
1160
+ mk_leading_zeros (rndd_sig, ebits+2 , rndd_sig_lz);
1161
+ dbg_decouple (" fpa2bv_rem_rndd_sig" , rndd_sig);
1162
+ dbg_decouple (" fpa2bv_rem_rndd_sig_lz" , rndd_sig_lz);
1163
+
1164
+ SASSERT (m_bv_util.get_bv_size (rndd_exp) == ebits+2 );
1165
+ SASSERT (m_bv_util.get_bv_size (y_exp_m1) == ebits);
1166
+
1167
+ expr_ref rndd_exp_eq_y_exp_m1 (m), y_sig_le_rndd_sig (m);
1168
+ rndd_exp_eq_y_exp_m1 = m.mk_eq (rndd_sig_lz, m_bv_util.mk_numeral (2 , ebits+2 ));
1169
+ dbg_decouple (" fpa2bv_rem_rndd_exp_eq_y_exp_m1" , rndd_exp_eq_y_exp_m1);
1170
+
1171
+ expr_ref y_sig_ext (m), y_sig_eq_rndd_sig (m);
1172
+ y_sig_ext = m_bv_util.mk_concat (m_bv_util.mk_zero_extend (2 , b_sig), m_bv_util.mk_numeral (0 , 2 ));
1173
+ y_sig_le_rndd_sig = m_bv_util.mk_sle (y_sig_ext, rndd_sig);
1174
+ y_sig_eq_rndd_sig = m.mk_eq (y_sig_ext, rndd_sig);
1175
+ dbg_decouple (" fpa2bv_rem_y_sig_ext" , y_sig_ext);
1176
+ dbg_decouple (" fpa2bv_rem_y_sig_le_rndd_sig" , y_sig_le_rndd_sig);
1177
+ dbg_decouple (" fpa2bv_rem_y_sig_eq_rndd_sig" , y_sig_eq_rndd_sig);
1178
+
1179
+ expr_ref sub_cnd (m);
1180
+ sub_cnd = m.mk_or (m.mk_and (rndd_exp_eq_y_exp_m1, y_sig_le_rndd_sig, m.mk_not (y_sig_eq_rndd_sig)),
1181
+ m.mk_and (rndd_exp_eq_y_exp_m1, y_sig_eq_rndd_sig, m.mk_not (huge_div_is_even)));
1189
1182
dbg_decouple (" fpa2bv_rem_sub_cnd" , sub_cnd);
1190
- dbg_decouple (" fpa2bv_rem_add_cnd" , add_cnd);
1191
- dbg_decouple (" fpa2bv_rem_rounded_add_y" , rounded_add_y);
1192
- dbg_decouple (" fpa2bv_rem_rounded_sub_y" , rounded_sub_y);
1193
- dbg_decouple (" fpa2bv_rem_rndd" , rndd);
1194
1183
1195
- mk_ite (add_cnd, rounded_add_y, rndd, v7);
1196
- mk_ite (sub_cnd, rounded_sub_y, v7, v7);
1184
+ expr_ref rndd (m), rounded_sub_y (m), rounded_add_y (m);
1185
+ round (s, rne_bv, rndd_sgn, rndd_sig, rndd_exp, rndd);
1186
+ mk_sub (s, rne_bv, rndd, y, rounded_sub_y);
1187
+ mk_ite (sub_cnd, rounded_sub_y, rndd, v7);
1197
1188
1198
1189
// And finally, we tie them together.
1199
1190
mk_ite (c6, v6, v7, result);
0 commit comments