mirror of
https://github.com/Z3Prover/z3
synced 2025-06-19 12:23:38 +00:00
Fixed potential memory leakage issues in fpa2bv_converfter
This commit is contained in:
parent
3ffcea0fe4
commit
6db0a15d29
1 changed files with 200 additions and 176 deletions
|
@ -3,15 +3,15 @@ Copyright (c) 2012 Microsoft Corporation
|
||||||
|
|
||||||
Module Name:
|
Module Name:
|
||||||
|
|
||||||
fpa2bv_converter.cpp
|
fpa2bv_converter.cpp
|
||||||
|
|
||||||
Abstract:
|
Abstract:
|
||||||
|
|
||||||
Conversion routines for Floating Point -> Bit-Vector
|
Conversion routines for Floating Point -> Bit-Vector
|
||||||
|
|
||||||
Author:
|
Author:
|
||||||
|
|
||||||
Christoph (cwinter) 2012-02-09
|
Christoph (cwinter) 2012-02-09
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * ar
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expr_ref bv_sgn(m), bv_sig(m), e(m), biased_exp(m);
|
expr_ref bv_sgn(m), bv_sig(m), e(m), biased_exp(m);
|
||||||
bv_sgn = m_bv_util.mk_numeral( (sign) ? 1 : 0, 1);
|
bv_sgn = m_bv_util.mk_numeral((sign) ? 1 : 0, 1);
|
||||||
bv_sig = m_bv_util.mk_numeral(rational(sig), sbits-1);
|
bv_sig = m_bv_util.mk_numeral(rational(sig), sbits-1);
|
||||||
e = m_bv_util.mk_numeral(exp, ebits);
|
e = m_bv_util.mk_numeral(exp, ebits);
|
||||||
|
|
||||||
|
@ -183,8 +183,8 @@ void fpa2bv_converter::mk_const(func_decl * f, expr_ref & result) {
|
||||||
std::string name = f->get_name().str();
|
std::string name = f->get_name().str();
|
||||||
|
|
||||||
sgn = mk_fresh_const((p + "_sgn_" + name).c_str(), 1);
|
sgn = mk_fresh_const((p + "_sgn_" + name).c_str(), 1);
|
||||||
s = mk_fresh_const((p + "_sig_" + name).c_str(), sbits - 1);
|
|
||||||
e = mk_fresh_const((p + "_exp_" + name).c_str(), ebits);
|
e = mk_fresh_const((p + "_exp_" + name).c_str(), ebits);
|
||||||
|
s = mk_fresh_const((p + "_sig_" + name).c_str(), sbits-1);
|
||||||
#else
|
#else
|
||||||
app_ref bv(m);
|
app_ref bv(m);
|
||||||
unsigned bv_sz = 1 + ebits + (sbits - 1);
|
unsigned bv_sz = 1 + ebits + (sbits - 1);
|
||||||
|
@ -215,8 +215,8 @@ void fpa2bv_converter::mk_var(unsigned base_inx, sort * srt, expr_ref & result)
|
||||||
expr_ref sgn(m), s(m), e(m);
|
expr_ref sgn(m), s(m), e(m);
|
||||||
|
|
||||||
sgn = m.mk_var(base_inx, m_bv_util.mk_sort(1));
|
sgn = m.mk_var(base_inx, m_bv_util.mk_sort(1));
|
||||||
s = m.mk_var(base_inx + 1, m_bv_util.mk_sort(sbits-1));
|
s = m.mk_var(base_inx+1, m_bv_util.mk_sort(sbits-1));
|
||||||
e = m.mk_var(base_inx + 2, m_bv_util.mk_sort(ebits));
|
e = m.mk_var(base_inx+2, m_bv_util.mk_sort(ebits));
|
||||||
|
|
||||||
mk_fp(sgn, e, s, result);
|
mk_fp(sgn, e, s, result);
|
||||||
}
|
}
|
||||||
|
@ -316,11 +316,11 @@ void fpa2bv_converter::mk_rm_const(func_decl * f, expr_ref & result) {
|
||||||
|
|
||||||
expr_ref bv3(m);
|
expr_ref bv3(m);
|
||||||
bv3 = m.mk_fresh_const(
|
bv3 = m.mk_fresh_const(
|
||||||
#ifdef Z3DEBUG
|
#ifdef Z3DEBUG
|
||||||
"fpa2bv_rm"
|
"fpa2bv_rm"
|
||||||
#else
|
#else
|
||||||
0
|
0
|
||||||
#endif
|
#endif
|
||||||
, m_bv_util.mk_sort(3));
|
, m_bv_util.mk_sort(3));
|
||||||
|
|
||||||
mk_rm(bv3, result);
|
mk_rm(bv3, result);
|
||||||
|
@ -1136,7 +1136,9 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args,
|
||||||
v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, x, y);
|
v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_UNSPECIFIED, x, y);
|
||||||
|
|
||||||
// Note: This requires BR_REWRITE_FULL afterwards.
|
// Note: This requires BR_REWRITE_FULL afterwards.
|
||||||
result = m.mk_ite(c, v, m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_I, x, y));
|
expr_ref min_i(m);
|
||||||
|
min_i = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MIN_I, x, y);
|
||||||
|
m_simp.mk_ite(c, v, min_i, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||||
|
@ -1163,8 +1165,7 @@ void fpa2bv_converter::mk_min_i(func_decl * f, unsigned num, expr * const * args
|
||||||
expr_ref lt(m);
|
expr_ref lt(m);
|
||||||
mk_float_lt(f, num, args, lt);
|
mk_float_lt(f, num, args, lt);
|
||||||
|
|
||||||
result = y;
|
mk_ite(lt, x, y, result);
|
||||||
mk_ite(lt, x, result, result);
|
|
||||||
mk_ite(both_zero, y, result, result);
|
mk_ite(both_zero, y, result, result);
|
||||||
mk_ite(y_is_nan, x, result, result);
|
mk_ite(y_is_nan, x, result, result);
|
||||||
mk_ite(x_is_nan, y, result, result);
|
mk_ite(x_is_nan, y, result, result);
|
||||||
|
@ -1221,7 +1222,9 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args,
|
||||||
v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, x, y);
|
v = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_UNSPECIFIED, x, y);
|
||||||
|
|
||||||
// Note: This requires BR_REWRITE_FULL afterwards.
|
// Note: This requires BR_REWRITE_FULL afterwards.
|
||||||
result = m.mk_ite(c, v, m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_I, x, y));
|
expr_ref max_i(m);
|
||||||
|
max_i = m.mk_app(m_util.get_family_id(), OP_FPA_INTERNAL_MAX_I, x, y);
|
||||||
|
m_simp.mk_ite(c, v, max_i, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||||
|
@ -1242,14 +1245,14 @@ void fpa2bv_converter::mk_max_i(func_decl * f, unsigned num, expr * const * args
|
||||||
mk_is_nan(y, y_is_nan);
|
mk_is_nan(y, y_is_nan);
|
||||||
mk_pzero(f, pzero);
|
mk_pzero(f, pzero);
|
||||||
|
|
||||||
expr_ref sgn_diff(m);
|
expr_ref sgn_diff(m), sgn_eq(m);
|
||||||
sgn_diff = m.mk_not(m.mk_eq(x_sgn, y_sgn));
|
sgn_eq = m.mk_eq(x_sgn, y_sgn);
|
||||||
|
sgn_diff = m.mk_not(sgn_eq);
|
||||||
|
|
||||||
expr_ref gt(m);
|
expr_ref gt(m);
|
||||||
mk_float_gt(f, num, args, gt);
|
mk_float_gt(f, num, args, gt);
|
||||||
|
|
||||||
result = y;
|
mk_ite(gt, x, y, result);
|
||||||
mk_ite(gt, x, result, result);
|
|
||||||
mk_ite(both_zero, y, result, result);
|
mk_ite(both_zero, y, result, result);
|
||||||
mk_ite(y_is_nan, x, result, result);
|
mk_ite(y_is_nan, x, result, result);
|
||||||
mk_ite(x_is_nan, y, result, result);
|
mk_ite(x_is_nan, y, result, result);
|
||||||
|
@ -1818,8 +1821,9 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr *
|
||||||
dbg_decouple("fpa2bv_r2i_unpacked_sig", a_sig);
|
dbg_decouple("fpa2bv_r2i_unpacked_sig", a_sig);
|
||||||
dbg_decouple("fpa2bv_r2i_unpacked_exp", a_exp);
|
dbg_decouple("fpa2bv_r2i_unpacked_exp", a_exp);
|
||||||
|
|
||||||
expr_ref xzero(m);
|
expr_ref xzero(m), sgn_eq_1(m);
|
||||||
mk_ite(m.mk_eq(a_sgn, one_1), nzero, pzero, xzero);
|
sgn_eq_1 = m.mk_eq(a_sgn, one_1);
|
||||||
|
mk_ite(sgn_eq_1, nzero, pzero, xzero);
|
||||||
|
|
||||||
// exponent < 0 -> 0/1
|
// exponent < 0 -> 0/1
|
||||||
expr_ref exp_lt_zero(m), exp_h(m);
|
expr_ref exp_lt_zero(m), exp_h(m);
|
||||||
|
@ -1831,7 +1835,7 @@ void fpa2bv_converter::mk_round_to_integral(func_decl * f, unsigned num, expr *
|
||||||
expr_ref pone(m), none(m), xone(m), c421(m), c422(m), c423(m), t1(m), t2(m), tie(m), v42(m), exp_lt_m1(m);
|
expr_ref pone(m), none(m), xone(m), c421(m), c422(m), c423(m), t1(m), t2(m), tie(m), v42(m), exp_lt_m1(m);
|
||||||
mk_one(f, zero_1, pone);
|
mk_one(f, zero_1, pone);
|
||||||
mk_one(f, one_1, none);
|
mk_one(f, one_1, none);
|
||||||
mk_ite(m.mk_eq(a_sgn, one_1), none, pone, xone);
|
mk_ite(sgn_eq_1, none, pone, xone);
|
||||||
|
|
||||||
expr_ref pow_2_sbitsm1(m), m1(m);
|
expr_ref pow_2_sbitsm1(m), m1(m);
|
||||||
pow_2_sbitsm1 = m_bv_util.mk_numeral(fu().fm().m_powers2(sbits - 1), sbits);
|
pow_2_sbitsm1 = m_bv_util.mk_numeral(fu().fm().m_powers2(sbits - 1), sbits);
|
||||||
|
@ -2004,7 +2008,6 @@ void fpa2bv_converter::mk_float_eq(func_decl * f, unsigned num, expr * const * a
|
||||||
expr_ref c3t4(m), c2else(m);
|
expr_ref c3t4(m), c2else(m);
|
||||||
m_simp.mk_ite(c3, m.mk_false(), t4, c3t4);
|
m_simp.mk_ite(c3, m.mk_false(), t4, c3t4);
|
||||||
m_simp.mk_ite(c2, m.mk_true(), c3t4, c2else);
|
m_simp.mk_ite(c2, m.mk_true(), c3t4, c2else);
|
||||||
|
|
||||||
m_simp.mk_ite(c1, m.mk_false(), c2else, result);
|
m_simp.mk_ite(c1, m.mk_false(), c2else, result);
|
||||||
|
|
||||||
TRACE("fpa2bv_float_eq", tout << "FLOAT_EQ = " << mk_ismt2_pp(result, m) << std::endl; );
|
TRACE("fpa2bv_float_eq", tout << "FLOAT_EQ = " << mk_ismt2_pp(result, m) << std::endl; );
|
||||||
|
@ -2596,7 +2599,7 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar
|
||||||
SASSERT(m_bv_util.get_bv_size(sig) == sbits);
|
SASSERT(m_bv_util.get_bv_size(sig) == sbits);
|
||||||
SASSERT(m_bv_util.get_bv_size(exp) == ebits);
|
SASSERT(m_bv_util.get_bv_size(exp) == ebits);
|
||||||
|
|
||||||
expr_ref rsig(m), bit(m), zero(m), one(m), two(m), bv0(m), bv1(m);
|
expr_ref rsig(m), bit(m), bit_eq_1(m), rsig_mul_2(m), zero(m), one(m), two(m), bv0(m), bv1(m);
|
||||||
zero = m_arith_util.mk_numeral(rational(0), rs);
|
zero = m_arith_util.mk_numeral(rational(0), rs);
|
||||||
one = m_arith_util.mk_numeral(rational(1), rs);
|
one = m_arith_util.mk_numeral(rational(1), rs);
|
||||||
two = m_arith_util.mk_numeral(rational(2), rs);
|
two = m_arith_util.mk_numeral(rational(2), rs);
|
||||||
|
@ -2605,8 +2608,10 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar
|
||||||
rsig = one;
|
rsig = one;
|
||||||
for (unsigned i = sbits - 2; i != (unsigned)-1; i--) {
|
for (unsigned i = sbits - 2; i != (unsigned)-1; i--) {
|
||||||
bit = m_bv_util.mk_extract(i, i, sig);
|
bit = m_bv_util.mk_extract(i, i, sig);
|
||||||
rsig = m_arith_util.mk_add(m_arith_util.mk_mul(rsig, two),
|
bit_eq_1 = m.mk_eq(bit, bv1);
|
||||||
m.mk_ite(m.mk_eq(bit, bv1), one, zero));
|
rsig_mul_2 = m_arith_util.mk_mul(rsig, two);
|
||||||
|
rsig = m_arith_util.mk_add(rsig_mul_2,
|
||||||
|
m.mk_ite(bit_eq_1, one, zero));
|
||||||
}
|
}
|
||||||
|
|
||||||
const mpz & p2 = fu().fm().m_powers2(sbits - 1);
|
const mpz & p2 = fu().fm().m_powers2(sbits - 1);
|
||||||
|
@ -2625,30 +2630,37 @@ void fpa2bv_converter::mk_to_real(func_decl * f, unsigned num, expr * const * ar
|
||||||
dbg_decouple("fpa2bv_to_real_exp_abs", exp);
|
dbg_decouple("fpa2bv_to_real_exp_abs", exp);
|
||||||
SASSERT(m_bv_util.get_bv_size(exp_abs) == ebits + 1);
|
SASSERT(m_bv_util.get_bv_size(exp_abs) == ebits + 1);
|
||||||
|
|
||||||
expr_ref exp2(m), prev_bit(m);
|
expr_ref exp2(m), exp2_mul_2(m), prev_bit(m);
|
||||||
exp2 = zero;
|
exp2 = zero;
|
||||||
for (unsigned i = ebits; i != (unsigned)-1; i--) {
|
for (unsigned i = ebits; i != (unsigned)-1; i--) {
|
||||||
bit = m_bv_util.mk_extract(i, i, exp_abs);
|
bit = m_bv_util.mk_extract(i, i, exp_abs);
|
||||||
exp2 = m_arith_util.mk_add(m_arith_util.mk_mul(exp2, two),
|
bit_eq_1 = m.mk_eq(bit, bv1);
|
||||||
m.mk_ite(m.mk_eq(bit, bv1), one, zero));
|
exp2_mul_2 = m_arith_util.mk_mul(exp2, two);
|
||||||
|
exp2 = m_arith_util.mk_add(exp2_mul_2,
|
||||||
|
m.mk_ite(bit_eq_1, one, zero));
|
||||||
prev_bit = bit;
|
prev_bit = bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
exp2 = m.mk_ite(exp_is_neg, m_arith_util.mk_div(one, exp2), exp2);
|
expr_ref one_div_exp2(m);
|
||||||
|
one_div_exp2 = m_arith_util.mk_div(one, exp2);
|
||||||
|
exp2 = m.mk_ite(exp_is_neg, one_div_exp2, exp2);
|
||||||
dbg_decouple("fpa2bv_to_real_exp2", exp2);
|
dbg_decouple("fpa2bv_to_real_exp2", exp2);
|
||||||
|
|
||||||
expr_ref res(m), two_exp2(m);
|
expr_ref res(m), two_exp2(m), minus_res(m);
|
||||||
two_exp2 = m_arith_util.mk_power(two, exp2);
|
two_exp2 = m_arith_util.mk_power(two, exp2);
|
||||||
res = m_arith_util.mk_mul(rsig, two_exp2);
|
res = m_arith_util.mk_mul(rsig, two_exp2);
|
||||||
res = m.mk_ite(m.mk_eq(sgn, bv1), m_arith_util.mk_uminus(res), res);
|
minus_res = m_arith_util.mk_uminus(res);
|
||||||
|
res = m.mk_ite(m.mk_eq(sgn, bv1), minus_res, res);
|
||||||
dbg_decouple("fpa2bv_to_real_sig_times_exp2", res);
|
dbg_decouple("fpa2bv_to_real_sig_times_exp2", res);
|
||||||
|
|
||||||
TRACE("fpa2bv_to_real", tout << "rsig = " << mk_ismt2_pp(rsig, m) << std::endl;
|
TRACE("fpa2bv_to_real", tout << "rsig = " << mk_ismt2_pp(rsig, m) << std::endl;
|
||||||
tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;);
|
tout << "exp2 = " << mk_ismt2_pp(exp2, m) << std::endl;);
|
||||||
|
|
||||||
|
expr_ref unspec(m);
|
||||||
|
unspec = mk_to_real_unspecified(ebits, sbits);
|
||||||
result = m.mk_ite(x_is_zero, zero, res);
|
result = m.mk_ite(x_is_zero, zero, res);
|
||||||
result = m.mk_ite(x_is_inf, mk_to_real_unspecified(ebits, sbits), result);
|
result = m.mk_ite(x_is_inf, unspec, result);
|
||||||
result = m.mk_ite(x_is_nan, mk_to_real_unspecified(ebits, sbits), result);
|
result = m.mk_ite(x_is_nan, unspec, result);
|
||||||
|
|
||||||
SASSERT(is_well_sorted(m, result));
|
SASSERT(is_well_sorted(m, result));
|
||||||
}
|
}
|
||||||
|
@ -2702,10 +2714,11 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
|
||||||
|
|
||||||
// Special case: x != 0
|
// Special case: x != 0
|
||||||
expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m);
|
expr_ref is_neg_bit(m), exp_too_large(m), sig_4(m), exp_2(m);
|
||||||
expr_ref is_neg(m), x_abs(m);
|
expr_ref is_neg(m), x_abs(m), neg_x(m);
|
||||||
is_neg_bit = m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, x);
|
is_neg_bit = m_bv_util.mk_extract(bv_sz - 1, bv_sz - 1, x);
|
||||||
is_neg = m.mk_eq(is_neg_bit, bv1_1);
|
is_neg = m.mk_eq(is_neg_bit, bv1_1);
|
||||||
x_abs = m.mk_ite(is_neg, m_bv_util.mk_bv_neg(x), x);
|
neg_x = m_bv_util.mk_bv_neg(x);
|
||||||
|
x_abs = m.mk_ite(is_neg, neg_x, x);
|
||||||
dbg_decouple("fpa2bv_to_fp_signed_is_neg", is_neg);
|
dbg_decouple("fpa2bv_to_fp_signed_is_neg", is_neg);
|
||||||
// x_abs has an extra bit in the front.
|
// x_abs has an extra bit in the front.
|
||||||
// x_abs is [bv_sz-1, bv_sz-2] . [bv_sz-3 ... 0] * 2^(bv_sz-2)
|
// x_abs is [bv_sz-1, bv_sz-2] . [bv_sz-3 ... 0] * 2^(bv_sz-2)
|
||||||
|
@ -2762,7 +2775,7 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
|
||||||
// exp_sz < exp_worst_case_sz and exp >= 0.
|
// exp_sz < exp_worst_case_sz and exp >= 0.
|
||||||
// Take the maximum legal exponent; this
|
// Take the maximum legal exponent; this
|
||||||
// allows us to keep the most precision.
|
// allows us to keep the most precision.
|
||||||
expr_ref max_exp(m), max_exp_bvsz(m);
|
expr_ref max_exp(m), max_exp_bvsz(m), zero_sig_sz(m);
|
||||||
mk_max_exp(exp_sz, max_exp);
|
mk_max_exp(exp_sz, max_exp);
|
||||||
max_exp_bvsz = m_bv_util.mk_zero_extend(bv_sz - exp_sz, max_exp);
|
max_exp_bvsz = m_bv_util.mk_zero_extend(bv_sz - exp_sz, max_exp);
|
||||||
|
|
||||||
|
@ -2770,7 +2783,8 @@ void fpa2bv_converter::mk_to_fp_signed(func_decl * f, unsigned num, expr * const
|
||||||
max_exp_bvsz,
|
max_exp_bvsz,
|
||||||
m_bv_util.mk_numeral(1, bv_sz)),
|
m_bv_util.mk_numeral(1, bv_sz)),
|
||||||
s_exp);
|
s_exp);
|
||||||
sig_4 = m.mk_ite(exp_too_large, m_bv_util.mk_numeral(0, sig_sz), sig_4);
|
zero_sig_sz = m_bv_util.mk_numeral(0, sig_sz);
|
||||||
|
sig_4 = m.mk_ite(exp_too_large, zero_sig_sz, sig_4);
|
||||||
exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2);
|
exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2);
|
||||||
}
|
}
|
||||||
dbg_decouple("fpa2bv_to_fp_signed_exp_too_large", exp_too_large);
|
dbg_decouple("fpa2bv_to_fp_signed_exp_too_large", exp_too_large);
|
||||||
|
@ -2894,7 +2908,7 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con
|
||||||
// exp_sz < exp_worst_case_sz and exp >= 0.
|
// exp_sz < exp_worst_case_sz and exp >= 0.
|
||||||
// Take the maximum legal exponent; this
|
// Take the maximum legal exponent; this
|
||||||
// allows us to keep the most precision.
|
// allows us to keep the most precision.
|
||||||
expr_ref max_exp(m), max_exp_bvsz(m);
|
expr_ref max_exp(m), max_exp_bvsz(m), zero_sig_sz(m);
|
||||||
mk_max_exp(exp_sz, max_exp);
|
mk_max_exp(exp_sz, max_exp);
|
||||||
max_exp_bvsz = m_bv_util.mk_zero_extend(bv_sz - exp_sz, max_exp);
|
max_exp_bvsz = m_bv_util.mk_zero_extend(bv_sz - exp_sz, max_exp);
|
||||||
|
|
||||||
|
@ -2902,7 +2916,8 @@ void fpa2bv_converter::mk_to_fp_unsigned(func_decl * f, unsigned num, expr * con
|
||||||
max_exp_bvsz,
|
max_exp_bvsz,
|
||||||
m_bv_util.mk_numeral(1, bv_sz)),
|
m_bv_util.mk_numeral(1, bv_sz)),
|
||||||
s_exp);
|
s_exp);
|
||||||
sig_4 = m.mk_ite(exp_too_large, m_bv_util.mk_numeral(0, sig_sz), sig_4);
|
zero_sig_sz = m_bv_util.mk_numeral(0, sig_sz);
|
||||||
|
sig_4 = m.mk_ite(exp_too_large, zero_sig_sz, sig_4);
|
||||||
exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2);
|
exp_2 = m.mk_ite(exp_too_large, max_exp, exp_2);
|
||||||
}
|
}
|
||||||
dbg_decouple("fpa2bv_to_fp_unsigned_exp_too_large", exp_too_large);
|
dbg_decouple("fpa2bv_to_fp_unsigned_exp_too_large", exp_too_large);
|
||||||
|
@ -2947,7 +2962,9 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const *
|
||||||
else
|
else
|
||||||
nanv = mk_to_ieee_bv_unspecified(ebits, sbits);
|
nanv = mk_to_ieee_bv_unspecified(ebits, sbits);
|
||||||
|
|
||||||
result = m.mk_ite(x_is_nan, nanv, m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s));
|
expr_ref sgn_e_s(m);
|
||||||
|
sgn_e_s = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s);
|
||||||
|
m_simp.mk_ite(x_is_nan, nanv, sgn_e_s, result);
|
||||||
|
|
||||||
SASSERT(is_well_sorted(m, result));
|
SASSERT(is_well_sorted(m, result));
|
||||||
}
|
}
|
||||||
|
@ -3016,14 +3033,15 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args
|
||||||
sig_sz = m_bv_util.get_bv_size(sig);
|
sig_sz = m_bv_util.get_bv_size(sig);
|
||||||
SASSERT(sig_sz >= (bv_sz + 3));
|
SASSERT(sig_sz >= (bv_sz + 3));
|
||||||
|
|
||||||
expr_ref exp_m_lz(m), e_m_lz_m_bv_sz(m), shift(m), bv0_e2(m), shift_abs(m);
|
expr_ref exp_m_lz(m), e_m_lz_m_bv_sz(m), shift(m), bv0_e2(m), shift_abs(m), shift_le_0(m);
|
||||||
exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp),
|
exp_m_lz = m_bv_util.mk_bv_sub(m_bv_util.mk_sign_extend(2, exp),
|
||||||
m_bv_util.mk_zero_extend(2, lz));
|
m_bv_util.mk_zero_extend(2, lz));
|
||||||
e_m_lz_m_bv_sz = m_bv_util.mk_bv_sub(exp_m_lz,
|
e_m_lz_m_bv_sz = m_bv_util.mk_bv_sub(exp_m_lz,
|
||||||
m_bv_util.mk_numeral(bv_sz - 1, ebits + 2));
|
m_bv_util.mk_numeral(bv_sz - 1, ebits + 2));
|
||||||
shift = m_bv_util.mk_bv_neg(e_m_lz_m_bv_sz);
|
shift = m_bv_util.mk_bv_neg(e_m_lz_m_bv_sz);
|
||||||
bv0_e2 = m_bv_util.mk_numeral(0, ebits + 2);
|
bv0_e2 = m_bv_util.mk_numeral(0, ebits + 2);
|
||||||
shift_abs = m.mk_ite(m_bv_util.mk_sle(shift, bv0_e2), e_m_lz_m_bv_sz, shift);
|
shift_le_0 = m_bv_util.mk_sle(shift, bv0_e2);
|
||||||
|
shift_abs = m.mk_ite(shift_le_0, e_m_lz_m_bv_sz, shift);
|
||||||
SASSERT(m_bv_util.get_bv_size(shift) == ebits + 2);
|
SASSERT(m_bv_util.get_bv_size(shift) == ebits + 2);
|
||||||
SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2);
|
SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2);
|
||||||
dbg_decouple("fpa2bv_to_bv_shift", shift);
|
dbg_decouple("fpa2bv_to_bv_shift", shift);
|
||||||
|
@ -3079,13 +3097,19 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args
|
||||||
rnd_has_overflown = m.mk_eq(rnd_overflow, bv1);
|
rnd_has_overflown = m.mk_eq(rnd_overflow, bv1);
|
||||||
dbg_decouple("fpa2bv_to_bv_rnd_has_overflown", rnd_has_overflown);
|
dbg_decouple("fpa2bv_to_bv_rnd_has_overflown", rnd_has_overflown);
|
||||||
|
|
||||||
if (is_signed)
|
if (is_signed) {
|
||||||
rnd = m.mk_ite(m.mk_eq(sgn, bv1), m_bv_util.mk_bv_neg(rnd), rnd);
|
expr_ref sgn_eq_1(m), neg_rnd(m);
|
||||||
|
sgn_eq_1 = m.mk_eq(sgn, bv1);
|
||||||
|
neg_rnd = m_bv_util.mk_bv_neg(rnd);
|
||||||
|
m_simp.mk_ite(sgn_eq_1, neg_rnd, rnd, rnd);
|
||||||
|
}
|
||||||
|
|
||||||
dbg_decouple("fpa2bv_to_bv_rnd", rnd);
|
dbg_decouple("fpa2bv_to_bv_rnd", rnd);
|
||||||
|
|
||||||
result = m.mk_ite(rnd_has_overflown, mk_to_ubv_unspecified(ebits, sbits, bv_sz), rnd);
|
expr_ref unspec(m);
|
||||||
result = m.mk_ite(c_in_limits, result, mk_to_ubv_unspecified(ebits, sbits, bv_sz));
|
unspec = mk_to_ubv_unspecified(ebits, sbits, bv_sz);
|
||||||
|
result = m.mk_ite(rnd_has_overflown, unspec, rnd);
|
||||||
|
result = m.mk_ite(c_in_limits, result, unspec);
|
||||||
result = m.mk_ite(c2, v2, result);
|
result = m.mk_ite(c2, v2, result);
|
||||||
result = m.mk_ite(c1, v1, result);
|
result = m.mk_ite(c1, v1, result);
|
||||||
|
|
||||||
|
@ -3571,14 +3595,14 @@ void fpa2bv_converter::mk_rounding_mode(func_decl * f, expr_ref & result)
|
||||||
}
|
}
|
||||||
|
|
||||||
void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) {
|
void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) {
|
||||||
#ifdef Z3DEBUG
|
#ifdef Z3DEBUG
|
||||||
return;
|
return;
|
||||||
// CMW: This works only for quantifier-free formulas.
|
// CMW: This works only for quantifier-free formulas.
|
||||||
expr_ref new_e(m);
|
expr_ref new_e(m);
|
||||||
new_e = m.mk_fresh_const(prefix, m.get_sort(e));
|
new_e = m.mk_fresh_const(prefix, m.get_sort(e));
|
||||||
m_extra_assertions.push_back(m.mk_eq(new_e, e));
|
m_extra_assertions.push_back(m.mk_eq(new_e, e));
|
||||||
e = new_e;
|
e = new_e;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref fpa2bv_converter::mk_rounding_decision(expr * bv_rm, expr * sgn, expr * last, expr * round, expr * sticky) {
|
expr_ref fpa2bv_converter::mk_rounding_decision(expr * bv_rm, expr * sgn, expr * last, expr * round, expr * sticky) {
|
||||||
|
@ -3598,7 +3622,7 @@ expr_ref fpa2bv_converter::mk_rounding_decision(expr * bv_rm, expr * sgn, expr *
|
||||||
expr * round_sticky[2] = { round, sticky };
|
expr * round_sticky[2] = { round, sticky };
|
||||||
last_or_sticky = m_bv_util.mk_bv_or(2, last_sticky);
|
last_or_sticky = m_bv_util.mk_bv_or(2, last_sticky);
|
||||||
round_or_sticky = m_bv_util.mk_bv_or(2, round_sticky);
|
round_or_sticky = m_bv_util.mk_bv_or(2, round_sticky);
|
||||||
not_last= m_bv_util.mk_bv_not(last);
|
not_last = m_bv_util.mk_bv_not(last);
|
||||||
not_round = m_bv_util.mk_bv_not(round);
|
not_round = m_bv_util.mk_bv_not(round);
|
||||||
not_sticky = m_bv_util.mk_bv_not(sticky);
|
not_sticky = m_bv_util.mk_bv_not(sticky);
|
||||||
not_lors = m_bv_util.mk_bv_not(last_or_sticky);
|
not_lors = m_bv_util.mk_bv_not(last_or_sticky);
|
||||||
|
@ -3724,7 +3748,7 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re
|
||||||
expr_ref beta(m);
|
expr_ref beta(m);
|
||||||
beta = m_bv_util.mk_bv_add(m_bv_util.mk_bv_sub(exp, lz), m_bv_util.mk_numeral(1, ebits+2));
|
beta = m_bv_util.mk_bv_add(m_bv_util.mk_bv_sub(exp, lz), m_bv_util.mk_numeral(1, ebits+2));
|
||||||
|
|
||||||
TRACE("fpa2bv_dbg", tout << "beta = " << mk_ismt2_pp(beta, m)<< std::endl; );
|
TRACE("fpa2bv_dbg", tout << "beta = " << mk_ismt2_pp(beta, m) << std::endl; );
|
||||||
SASSERT(is_well_sorted(m, beta));
|
SASSERT(is_well_sorted(m, beta));
|
||||||
|
|
||||||
dbg_decouple("fpa2bv_rnd_beta", beta);
|
dbg_decouple("fpa2bv_rnd_beta", beta);
|
||||||
|
@ -3745,9 +3769,9 @@ void fpa2bv_converter::round(sort * s, expr_ref & bv_rm, expr_ref & sgn, expr_re
|
||||||
dbg_decouple("fpa2bv_rnd_sig_before_shift", sig);
|
dbg_decouple("fpa2bv_rnd_sig_before_shift", sig);
|
||||||
|
|
||||||
unsigned sig_size = m_bv_util.get_bv_size(sig);
|
unsigned sig_size = m_bv_util.get_bv_size(sig);
|
||||||
SASSERT(sig_size == sbits+4);
|
SASSERT(sig_size == sbits + 4);
|
||||||
SASSERT(m_bv_util.get_bv_size(sigma) == ebits+2);
|
SASSERT(m_bv_util.get_bv_size(sigma) == ebits+2);
|
||||||
unsigned sigma_size = ebits+2;
|
unsigned sigma_size = ebits + 2;
|
||||||
|
|
||||||
expr_ref sigma_neg(m), sigma_cap(m), sigma_neg_capped(m), sigma_lt_zero(m), sig_ext(m),
|
expr_ref sigma_neg(m), sigma_cap(m), sigma_neg_capped(m), sigma_lt_zero(m), sig_ext(m),
|
||||||
rs_sig(m), ls_sig(m), big_sh_sig(m), sigma_le_cap(m);
|
rs_sig(m), ls_sig(m), big_sh_sig(m), sigma_le_cap(m);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue