Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/ir/constraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,55 @@ std::optional<Constraint> fusedApproximateAndPair(const Constraint& a,
return {};
}

bool isImmediateContradiction(const Constraint& c) {
using namespace Abstract;

auto* cc = std::get_if<Literal>(&c.term);
if (!cc) {
// Only operations on constants can be immediate contradictions.
return false;
}

auto minSigned = cc->type == Type::i32 ? std::numeric_limits<int32_t>::min()
: std::numeric_limits<int64_t>::min();
auto maxSigned = cc->type == Type::i32 ? std::numeric_limits<int32_t>::max()
: std::numeric_limits<int64_t>::max();
auto maxUnsigned = cc->type == Type::i32
? std::numeric_limits<uint32_t>::max()
: std::numeric_limits<uint64_t>::max();

switch (c.op) {
case LtS:
if (cc->getInteger() == minSigned) {
// Less than the lowest possible number.
return true;
}
break;
case LtU:
if (cc->getInteger() == 0) {
// Less than the lowest possible number.
return true;
}
break;
case GtS:
if (cc->getInteger() == maxSigned) {
// Greater than the highest possible number.
return true;
}
break;
case GtU:
if (cc->getUnsigned() == maxUnsigned) {
// Greater than the highest possible number.
return true;
}
break;
default: {
}
}

return false;
}

} // anonymous namespace

void AndedConstraintSet::approximateAnd(const Constraint& c) {
Expand All @@ -322,6 +371,12 @@ void AndedConstraintSet::approximateAnd(const Constraint& c) {
return;
}

// We don't store contradictions: identify them and mark us as such.
if (isImmediateContradiction(c)) {
setProvesEverything();
return;
}

auto result = proves(c);
if (result == True) {
// We already prove c to be true, so it adds nothing.
Expand Down
Loading