Skip to content

Commit

Permalink
fix: changes in CV computations for MUL, REMU, DIVU
Browse files Browse the repository at this point in the history
  • Loading branch information
saraseidl committed Aug 3, 2021
1 parent 88cb4ec commit c830015
Showing 1 changed file with 20 additions and 12 deletions.
32 changes: 20 additions & 12 deletions src/solver/monster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ fn compute_consistent_value(op: BVOperator, t: BitVector, d: OperandSide) -> Bit
BVOperator::Add | BVOperator::Sub | BVOperator::Equals => BitVector(random::<u64>()),
BVOperator::Mul => BitVector({
if t == BitVector(0) {
0
random::<u64>()
} else {
let mut r;
loop {
Expand All @@ -316,17 +316,19 @@ fn compute_consistent_value(op: BVOperator, t: BitVector, d: OperandSide) -> Bit
}),
BVOperator::Divu => match d {
OperandSide::Lhs => {
if (t == BitVector::ones()) || (t == BitVector(0)) {
if t == BitVector::ones() {

This comment has been minimized.

Copy link
@saraseidl

saraseidl Aug 9, 2021

Author Collaborator

x / s = ones: x = ones is a consistent value.

BitVector(random::<u64>())
} else if t == BitVector(0) {
BitVector(thread_rng().sample(Uniform::new_inclusive(0, u64::max_value() - 1)))
} else {
let mut y = BitVector(0);
while !(y != BitVector(0)) && !(y.mulo(t)) {
y = BitVector(
thread_rng().sample(Uniform::new_inclusive(0, u64::max_value())),
);
}
let y = BitVector(
thread_rng().sample(Uniform::new_inclusive(1, u64::max_value() / t.0)),
);

let range_start = (t * y).0;
let range_end = range_start.saturating_add(y.0 - 1);

y * t
BitVector(thread_rng().sample(Uniform::new_inclusive(range_start, range_end)))

This comment has been minimized.

Copy link
@saraseidl

saraseidl Aug 9, 2021

Author Collaborator

Missing consistent values:
x in [t*y ... (t + 1)y]
(x in [t
y ... ones] if (t + 1)*y overflows)

This comment has been minimized.

Copy link
@mstarzinger

mstarzinger Aug 17, 2021

Collaborator

Nice catch, this range seems to be missing even in the 2017 paper.

}
}
OperandSide::Rhs => {
Expand Down Expand Up @@ -361,10 +363,16 @@ fn compute_consistent_value(op: BVOperator, t: BitVector, d: OperandSide) -> Bit
},
BVOperator::Remu => match d {
OperandSide::Lhs => {
if t == BitVector::ones() {
BitVector::ones()
if t == BitVector::ones() || t > BitVector::ones() - t {

This comment has been minimized.

Copy link
@mstarzinger

mstarzinger Aug 17, 2021

Collaborator

If I understand correctly, then this condition could also be expressed as t > (BitVector::ones() >> 1), which semantically means t > ones / 2, correct? Would this be easier to read? Also, the second half of the condition seems to subsume the first half (in both cases).

t
} else {
BitVector(thread_rng().sample(Uniform::new_inclusive(t.0, BitVector::ones().0)))
let r = thread_rng().sample(Uniform::new_inclusive(2 * t.0, u64::max_value()));

This comment has been minimized.

Copy link
@saraseidl

saraseidl Aug 9, 2021

Author Collaborator

x % s = t
Either x = t ( as x = s * y + t for y = 0)
or x > 2t (x = s * y + t for y > 0 and s > t)


if r == 2 * t.0 {
t
} else {
BitVector(r)
}
}
}
OperandSide::Rhs => {
Expand Down

2 comments on commit c830015

@saraseidl
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds consistent values that haven't been considered before.

@mstarzinger
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! This commit LGTM.

Please sign in to comment.