mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
use native sdiv
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
bfcd75595e
commit
5a57636cd8
|
@ -724,11 +724,11 @@ namespace sls {
|
||||||
case OP_BSMOD:
|
case OP_BSMOD:
|
||||||
case OP_BSMOD_I:
|
case OP_BSMOD_I:
|
||||||
case OP_BSMOD0:
|
case OP_BSMOD0:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
case OP_BSDIV:
|
case OP_BSDIV:
|
||||||
case OP_BSDIV_I:
|
case OP_BSDIV_I:
|
||||||
case OP_BSDIV0:
|
case OP_BSDIV0:
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -916,15 +916,17 @@ namespace sls {
|
||||||
case OP_BSMUL_OVFL:
|
case OP_BSMUL_OVFL:
|
||||||
verbose_stream() << mk_pp(e, m) << "\n";
|
verbose_stream() << mk_pp(e, m) << "\n";
|
||||||
return false;
|
return false;
|
||||||
|
case OP_BSDIV:
|
||||||
|
case OP_BSDIV_I:
|
||||||
|
case OP_BSDIV0:
|
||||||
|
return try_repair_sdiv(assign_value(e), wval(e, 0), wval(e, 1), i);
|
||||||
case OP_BSREM:
|
case OP_BSREM:
|
||||||
case OP_BSREM_I:
|
case OP_BSREM_I:
|
||||||
case OP_BSREM0:
|
case OP_BSREM0:
|
||||||
case OP_BSMOD:
|
case OP_BSMOD:
|
||||||
case OP_BSMOD_I:
|
case OP_BSMOD_I:
|
||||||
case OP_BSMOD0:
|
case OP_BSMOD0:
|
||||||
case OP_BSDIV:
|
|
||||||
case OP_BSDIV_I:
|
|
||||||
case OP_BSDIV0:
|
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
// these are currently compiled to udiv and urem.
|
// these are currently compiled to udiv and urem.
|
||||||
// there is an equation that enforces equality between the semantics
|
// there is an equation that enforces equality between the semantics
|
||||||
|
@ -1223,6 +1225,51 @@ namespace sls {
|
||||||
return a.set_random(m_rand);
|
return a.set_random(m_rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool bv_eval::try_repair_sdiv(bvect const& e, bvval& a, bvval& b, unsigned i) {
|
||||||
|
|
||||||
|
bool sign_a = a.sign();
|
||||||
|
bool sign_b = b.sign();
|
||||||
|
bool sign_e = e.get(a.bw - 1);
|
||||||
|
|
||||||
|
// y = 0, x >= 0 -> -1
|
||||||
|
if (i == 0 && b.is_zero() && a.is_ones(e) && a.try_set(m_zero))
|
||||||
|
return true;
|
||||||
|
if (i == 0 && b.is_zero() && a.is_ones(e) && a.try_set_bit(a.bw - 1, false))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (i == 1 && !sign_a && a.is_ones(e) && b.try_set(m_zero))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// y = 0, x < 0 -> 1
|
||||||
|
if (i == 0 && b.is_zero() && a.is_one(e) && a.try_set(m_minus_one))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (i == 1 && sign_a && a.is_one(e) && b.try_set(m_zero))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// x = 0, y != 0 -> 0
|
||||||
|
if (i == 0 && a.is_zero(e) && !b.is_zero() && a.try_set(m_zero))
|
||||||
|
return true;
|
||||||
|
if (i == 1 && a.is_zero(e) && a.is_zero() && b.try_set_bit(ctx.rand(a.bw), true))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// e = x udiv y
|
||||||
|
// e = 0 => x != ones
|
||||||
|
// y = 0 => e = -1 // nothing to repair on a
|
||||||
|
// e != -1 => max(y) >=u e
|
||||||
|
|
||||||
|
//IF_VERBOSE(0, verbose_stream() << "sdiv " << e << " " << a << " " << b << "\n";);
|
||||||
|
|
||||||
|
// e = udiv(abs(x), abs(y))
|
||||||
|
// x > 0, y < 0 -> -e
|
||||||
|
// x < 0, y > 0 -> -e
|
||||||
|
// x > 0, y > 0 -> e
|
||||||
|
// x < 0, y < 0 -> e
|
||||||
|
|
||||||
|
return try_repair_udiv(e, a, b, i);
|
||||||
|
}
|
||||||
|
|
||||||
bool bv_eval::try_repair_bnot(bvect const& e, bvval& a) {
|
bool bv_eval::try_repair_bnot(bvect const& e, bvval& a) {
|
||||||
for (unsigned i = 0; i < a.nw; ++i)
|
for (unsigned i = 0; i < a.nw; ++i)
|
||||||
m_tmp[i] = ~e[i];
|
m_tmp[i] = ~e[i];
|
||||||
|
|
|
@ -110,6 +110,7 @@ namespace sls {
|
||||||
bool try_repair_lshr1(bvect const& e, bvval const& a, bvval& b);
|
bool try_repair_lshr1(bvect const& e, bvval const& a, bvval& b);
|
||||||
bool try_repair_ashr0(bvect const& e, bvval& a, bvval const& b);
|
bool try_repair_ashr0(bvect const& e, bvval& a, bvval const& b);
|
||||||
bool try_repair_ashr1(bvect const& e, bvval const& a, bvval& b);
|
bool try_repair_ashr1(bvect const& e, bvval const& a, bvval& b);
|
||||||
|
bool try_repair_sdiv(bvect const& e, bvval& a, bvval& b, unsigned i);
|
||||||
bool try_repair_bit2bool(bvval& a, unsigned idx);
|
bool try_repair_bit2bool(bvval& a, unsigned idx);
|
||||||
bool try_repair_udiv(bvect const& e, bvval& a, bvval& b, unsigned i);
|
bool try_repair_udiv(bvect const& e, bvval& a, bvval& b, unsigned i);
|
||||||
bool try_repair_urem(bvect const& e, bvval& a, bvval& b, unsigned i);
|
bool try_repair_urem(bvect const& e, bvval& a, bvval& b, unsigned i);
|
||||||
|
@ -126,6 +127,7 @@ namespace sls {
|
||||||
bool try_repair_comp(bvect const& e, bvval& a, bvval& b, unsigned i);
|
bool try_repair_comp(bvect const& e, bvval& a, bvval& b, unsigned i);
|
||||||
bool try_repair_eq(bool is_true, bvval& a, bvval const& b);
|
bool try_repair_eq(bool is_true, bvval& a, bvval const& b);
|
||||||
bool try_repair_eq(app* e, unsigned i);
|
bool try_repair_eq(app* e, unsigned i);
|
||||||
|
|
||||||
bool try_repair_int2bv(bvect const& e, expr* arg);
|
bool try_repair_int2bv(bvect const& e, expr* arg);
|
||||||
void add_p2_1(bvval const& a, bvect& t) const;
|
void add_p2_1(bvval const& a, bvect& t) const;
|
||||||
|
|
||||||
|
|
|
@ -587,8 +587,16 @@ namespace sls {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (allow_costly_flips(mt))
|
if (allow_costly_flips(mt))
|
||||||
ctx.flip(v);
|
ctx.flip(v);
|
||||||
|
else if (false) {
|
||||||
|
sat::bool_var_set rotated;
|
||||||
|
unsigned budget = 100;
|
||||||
|
bool rot = ctx.try_rotate(v, rotated, budget);
|
||||||
|
(void)rot;
|
||||||
|
TRACE("bv", tout << "rotate " << v << " " << rot << " " << rotated << "\n";);
|
||||||
|
verbose_stream() << "rotate " << v << " " << rot << " " << rotated << "\n";
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace sls {
|
||||||
expr_ref bv_terms::ensure_binary(expr* e) {
|
expr_ref bv_terms::ensure_binary(expr* e) {
|
||||||
expr* x, * y;
|
expr* x, * y;
|
||||||
expr_ref r(m);
|
expr_ref r(m);
|
||||||
if (bv.is_bv_sdiv(e, x, y) || bv.is_bv_sdiv0(e, x, y) || bv.is_bv_sdivi(e, x, y))
|
if (false && (bv.is_bv_sdiv(e, x, y) || bv.is_bv_sdiv0(e, x, y) || bv.is_bv_sdivi(e, x, y)))
|
||||||
r = mk_sdiv(x, y);
|
r = mk_sdiv(x, y);
|
||||||
else if (bv.is_bv_smod(e, x, y) || bv.is_bv_smod0(e, x, y) || bv.is_bv_smodi(e, x, y))
|
else if (bv.is_bv_smod(e, x, y) || bv.is_bv_smod0(e, x, y) || bv.is_bv_smodi(e, x, y))
|
||||||
r = mk_smod(x, y);
|
r = mk_smod(x, y);
|
||||||
|
|
|
@ -369,3 +369,8 @@ inline std::ostream& operator<<(std::ostream& out, indexed_uint_set const& s) {
|
||||||
for (unsigned i : s) out << i << " ";
|
for (unsigned i : s) out << i << " ";
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, tracked_uint_set const& s) {
|
||||||
|
for (unsigned i : s) out << i << " ";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue