-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(BV, CP): Add propagators for bvshl and bvlshr #1085
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -307,3 +307,61 @@ let mul a b = | |
in | ||
concat (unknown (sz - width mid_bits - width low_bits) Ex.empty) @@ | ||
concat mid_bits low_bits | ||
|
||
let shl a b = | ||
(* If the minimum value for [b] is larger than the bitwidth, the result is | ||
zero. | ||
|
||
Otherwise, any low zero bit in [a] is also a zero bit in the result, and | ||
the minimum value for [b] also accounts for that many minimum zeros (e.g. | ||
?000 shifted by at least 2 has at least 5 low zeroes). | ||
|
||
NB: [increase_lower_bound b Z.zero] is the smallest positive integer that | ||
matches the bitlist pattern, and so is a lower bound. Ideally we would | ||
like to use the lower bound from the interval domain for [b] instead. *) | ||
match Z.to_int (increase_lower_bound b Z.zero) with | ||
| n when n < width a -> | ||
let low_zeros = Z.trailing_zeros @@ Z.lognot @@ a.bits_clr in | ||
if low_zeros + n >= width a then | ||
exact (width a) Z.zero (Ex.union (explanation a) (explanation b)) | ||
else if low_zeros + n > 0 then | ||
concat (unknown (width a - low_zeros - n) Ex.empty) @@ | ||
exact (low_zeros + n) Z.zero (Ex.union (explanation a) (explanation b)) | ||
Halbaroth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else | ||
unknown (width a) Ex.empty | ||
| _ | exception Z.Overflow -> | ||
exact (width a) Z.zero (explanation b) | ||
Comment on lines
+323
to
+333
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's bind There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this code is removed in #1144 I'd rather not — it would only add rebase conflicts. |
||
|
||
let lshr a b = | ||
(* If the minimum value for [b] is larger than the bitwidth, the result is | ||
zero. | ||
|
||
Otherwise, any high zero bit in [a] is also a zero bit in the result, and | ||
the minimum value for [b] also accounts for that many minimum zeros (e.g. | ||
000??? shifted by at least 2 is 00000?). | ||
|
||
NB: [increase_lower_bound b Z.zero] is the smallest positive integer that | ||
matches the bitlist pattern, and so is a lower bound. Ideally we would | ||
like to use the lower bound from the interval domain for [b] instead. *) | ||
match Z.to_int (increase_lower_bound b Z.zero) with | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same remark here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto |
||
| n when n < width a -> | ||
let sz = width a in | ||
if Z.testbit a.bits_clr (sz - 1) then (* MSB is zero *) | ||
let low_msb_zero = Z.numbits @@ Z.extract (Z.lognot a.bits_clr) 0 sz in | ||
let nb_msb_zeros = sz - low_msb_zero in | ||
assert (nb_msb_zeros > 0); | ||
let nb_zeros = nb_msb_zeros + n in | ||
if nb_zeros >= sz then | ||
exact sz Z.zero (Ex.union (explanation a) (explanation b)) | ||
else | ||
concat | ||
(exact nb_zeros Z.zero (Ex.union (explanation a) (explanation b))) | ||
(unknown (sz - nb_zeros) Ex.empty) | ||
else if n > 0 then | ||
concat | ||
(exact n Z.zero (explanation b)) | ||
(unknown (sz - n) Ex.empty) | ||
else | ||
unknown sz Ex.empty | ||
| _ | exception Z.Overflow -> | ||
exact (width a) Z.zero (explanation b) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit weird to use
increase_lower_bound
in order to extract the lower bound ofb
. I think we should write a specialization:Alternatively, we can rename
increase_lower_bound
because its name is not very descriptive but I have no good suggestions for it right now.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the comment above notes, we would want to use the bounds from the interval domain instead, so this should disappear at some point. I will clarify that
increase_lower_bound Z.zero
is the smallest positive valid lower bound.