88#include " smt/expr.h"
99#include " smt/exprs.h"
1010#include " smt/solver.h"
11+ #include " state_value.h"
1112#include " util/compiler.h"
1213#include " util/config.h"
1314#include < algorithm>
@@ -2635,8 +2636,11 @@ InlineAsm::InlineAsm(Type &type, string &&name, const string &asm_str,
26352636 std::move(attrs)) {}
26362637
26372638
2638- ICmp::ICmp (Type &type, string &&name, Cond cond, Value &a, Value &b)
2639- : Instr(type, std::move(name)), a(&a), b(&b), cond(cond), defined(cond != Any) {
2639+ ICmp::ICmp (Type &type, string &&name, Cond cond, Value &a, Value &b,
2640+ unsigned flags)
2641+ : Instr(type, std::move(name)), a(&a), b(&b), cond(cond), flags(flags),
2642+ defined(cond != Any) {
2643+ assert ((flags & SameSign) == flags);
26402644 if (!defined )
26412645 cond_name = getName () + " _cond" ;
26422646}
@@ -2684,34 +2688,36 @@ void ICmp::print(ostream &os) const {
26842688 case UGT: condtxt = " ugt " ; break ;
26852689 case Any: condtxt = " " ; break ;
26862690 }
2687- os << getName () << " = icmp " << condtxt << *a << " , " << b->getName ();
2691+ os << getName () << " = icmp " ;
2692+ if (flags & SameSign)
2693+ os << " samesign " ;
2694+ os << condtxt << *a << " , " << b->getName ();
26882695 switch (pcmode) {
26892696 case INTEGRAL: break ;
26902697 case PROVENANCE: os << " , use_provenance" ; break ;
26912698 case OFFSETONLY: os << " , offsetonly" ; break ;
26922699 }
26932700}
26942701
2695- static expr build_icmp_chain (const expr &var,
2696- const function<expr (ICmp::Cond)> &fn,
2697- ICmp::Cond cond = ICmp::Any,
2698- expr last = expr ()) {
2702+ static StateValue build_icmp_chain (const expr &var,
2703+ const function<StateValue (ICmp::Cond)> &fn,
2704+ ICmp::Cond cond = ICmp::Any,
2705+ StateValue last = StateValue ()) {
26992706 auto old_cond = cond;
27002707 cond = ICmp::Cond (cond - 1 );
27012708
27022709 if (old_cond == ICmp::Any)
27032710 return build_icmp_chain (var, fn, cond, fn (cond));
27042711
2705- auto e = expr ::mkIf (var == cond, fn (cond), last);
2712+ auto e = StateValue ::mkIf (var == cond, fn (cond), last);
27062713 return cond == 0 ? e : build_icmp_chain (var, fn, cond, std::move (e));
27072714}
27082715
27092716StateValue ICmp::toSMT (State &s) const {
27102717 auto &a_eval = s[*a];
27112718 auto &b_eval = s[*b];
27122719
2713- function<expr (const expr&, const expr&, Cond)> fn =
2714- [&](auto &av, auto &bv, Cond cond) {
2720+ auto cmp = [](const expr &av, const expr &bv, Cond cond) {
27152721 switch (cond) {
27162722 case EQ: return av == bv;
27172723 case NE: return av != bv;
@@ -2729,8 +2735,15 @@ StateValue ICmp::toSMT(State &s) const {
27292735 UNREACHABLE ();
27302736 };
27312737
2738+ function<StateValue (const expr &, const expr &, Cond)> fn =
2739+ [&](auto &av, auto &bv, Cond cond) -> StateValue {
2740+ return {cmp (av, bv, cond),
2741+ flags & SameSign ? av.sign () == bv.sign () : expr (true )};
2742+ };
2743+
27322744 if (isPtrCmp ()) {
2733- fn = [this , &s, fn](const expr &av, const expr &bv, Cond cond) {
2745+ fn = [this , &s, fn](const expr &av, const expr &bv,
2746+ Cond cond) -> StateValue {
27342747 auto &m = s.getMemory ();
27352748 Pointer lhs (m, av);
27362749 Pointer rhs (m, bv);
@@ -2742,7 +2755,7 @@ StateValue ICmp::toSMT(State &s) const {
27422755 return fn (lhs.getAddress (), rhs.getAddress (), cond);
27432756 case PROVENANCE:
27442757 assert (cond == EQ || cond == NE);
2745- return cond == EQ ? lhs == rhs : lhs != rhs;
2758+ return { cond == EQ ? lhs == rhs : lhs != rhs, true } ;
27462759 case OFFSETONLY:
27472760 return fn (lhs.getOffset (), rhs.getOffset (), cond);
27482761 }
@@ -2753,7 +2766,8 @@ StateValue ICmp::toSMT(State &s) const {
27532766 auto scalar = [&](const StateValue &a, const StateValue &b) -> StateValue {
27542767 auto fn2 = [&](Cond c) { return fn (a.value , b.value , c); };
27552768 auto v = cond != Any ? fn2 (cond) : build_icmp_chain (cond_var (), fn2);
2756- return { v.toBVBool (), a.non_poison && b.non_poison };
2769+ return {v.value .toBVBool (),
2770+ a.non_poison && b.non_poison && std::move (v.non_poison )};
27572771 };
27582772
27592773 auto &elem_ty = a->getType ();
@@ -2777,7 +2791,7 @@ expr ICmp::getTypeConstraints(const Function &f) const {
27772791}
27782792
27792793unique_ptr<Instr> ICmp::dup (Function &f, const string &suffix) const {
2780- return make_unique<ICmp>(getType (), getName () + suffix, cond, *a, *b);
2794+ return make_unique<ICmp>(getType (), getName () + suffix, cond, *a, *b, flags );
27812795}
27822796
27832797
0 commit comments