Skip to content

Commit

Permalink
fix: add/fix testcases for consistent value computation for REMU
Browse files Browse the repository at this point in the history
  • Loading branch information
saraseidl committed Aug 9, 2021
1 parent c830015 commit 70f6c02
Showing 1 changed file with 55 additions and 14 deletions.
69 changes: 55 additions & 14 deletions src/solver/monster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,42 +824,64 @@ mod tests {
// prove: Ey.(computed <> y == t) where <> is the binary bit vector operator
//

// compute inverse value for other operand
let inverse = match op {

This comment has been minimized.

Copy link
@mstarzinger

mstarzinger Aug 17, 2021

Collaborator

Since the implementation for computing the inverse is now the same for all operators, could we get rid of the match completely and just compute the inverse generically for all operators?

BVOperator::Add => t - computed,
BVOperator::Add => {
assert!(
is_invertible(op, computed, t, d.other()),
"consistent value has an inverse"
);
compute_inverse_value(op, computed, t, d.other())
}
BVOperator::Mul => {
assert!(
is_invertible(op, computed, t, d),
"choose values which are invertible..."
is_invertible(op, computed, t, d.other()),
"consistent value has an inverse"
);

compute_inverse_value(op, computed, t, d)
compute_inverse_value(op, computed, t, d.other())
}
BVOperator::Sltu => {
assert!(
is_invertible(op, computed, t, d.other()),
"consistent value has an inverse"
);
compute_inverse_value(op, computed, t, d.other())
}
BVOperator::Sltu => compute_inverse_value(op, computed, t, d),
BVOperator::Divu => {
assert!(is_invertible(op, computed, t, d));
compute_inverse_value(op, computed, t, d)
assert!(
is_invertible(op, computed, t, d.other()),
"consistent value has an inverse"
);
compute_inverse_value(op, computed, t, d.other())
}
BVOperator::Remu => {
assert!(
is_invertible(op, computed, t, d.other()),
"consistent value has an inverse"
);
compute_inverse_value(op, computed, t, d.other())
}
_ => unimplemented!(),
};

if d == OperandSide::Lhs {
assert_eq!(
f(inverse, computed),
f(computed, inverse),
t,
"{:?} {:?} {:?} == {:?}",
inverse,
op,
computed,
op,
inverse,
t
);
} else {
assert_eq!(
f(computed, inverse),
f(inverse, computed),
t,
"{:?} {:?} {:?} == {:?}",
computed,
op,
inverse,
op,
computed,
t
);
}
Expand Down Expand Up @@ -1115,4 +1137,23 @@ mod tests {
test_consistent_value_computation(SLTU, 0, side, f);
test_consistent_value_computation(SLTU, 1, side, f);
}

#[test]
fn compute_consistent_values_for_remu() {
let mut side = OperandSide::Lhs;

fn f(l: BitVector, r: BitVector) -> BitVector {
l % r
}

// test only for values which actually have a consistent value
test_consistent_value_computation(REMU, u64::max_value(), side, f);
test_consistent_value_computation(REMU, u64::max_value() / 2 + 7, side, f);
test_consistent_value_computation(REMU, 0, side, f);
test_consistent_value_computation(REMU, 7, side, f);

side = OperandSide::Rhs;
test_consistent_value_computation(REMU, u64::max_value(), side, f);
test_consistent_value_computation(REMU, 7, side, f);
}
}

2 comments on commit 70f6c02

@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.

Tests for consistent value computation for REMU.

Also, I think there was a tiny mixup in the tests between consistent and inverse values:
A computed consistent value for OperandSide d is checked by computing an inverse value for the other OperandSide.

@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, I like it! This commit LGTM.

Please sign in to comment.