-
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
arithmetic right shift behavior on overshift #323
Comments
However, see the following SBV issue that currently affects Cryptol behavior when computing signed right shifts with symbolic index amounts: LeventErkok/sbv#323
You're right on the use of I think there was a point in time where either SMTLib or one of the implementations I used (most likely Yices or CVC4) didn't support symbolic second arguments for shifts, and thus I had to do the expansion. But looks like they do now. Basically, it would involve changing the following two lines: https://github.com/LeventErkok/sbv/blob/master/Data/SBV/Core/Symbolic.hs#L139-L140 by removing the Also would be good to check about rotates; I couldn't find anything in the SMTLib if they support rotates these days; it can probably use the same trick. |
OK, I'll take a stab at making a patch. As for rotates, I don't think they are supported directly in SMTLib, or by the solvers. However, they can probably be encoded using shifts and bitwise or, I think. I don't know if that's better than table lookups or not. |
Thanks! Much appreciated. |
@robdockins There seems to be more to this story. See this: https://github.com/LeventErkok/sbv/blob/master/Data/SBV/Core/Model.hs#L834-L862 It appears I was thinking about arithmetic/logic shifts, but perhaps got the semantics wrong. Can you take a look at those comments to see what the appropriate semantics should be? |
@robdockins I believe I've fixed this issue, and cleaned-up the code base a bit along the way. Can you do some testing on the Cryptol side to see all is well? |
On the Cryptol side, we're now running into issues where SBV is generating code which applies Do you have an opinion? P.S. Thanks for getting a patch together so quickly! |
It's on purpose that the shifted value and the shiftee can have different bitwidths. This is also true for Cryptol, right?
So, I'd say it's completely legit to apply it to different widths. And that's precisely why we have the type: sShiftRight :: (SIntegral b, SIntegral a) => SBV a -> SBV b -> SBV a Note the separate Before figuring out who should fix what, we should first figure out what's going on. Is that a Cryptol issue, or something on the SBV side (either |
In that case it's definitely an SBV issue.
Yes, Cryptol also allows the bitwidths to be different. |
yep, that's a bug on SBV alright.. Will look at it later tonight. |
yeah, SMTLib doesn't allow mixed-bitwidth shifts.. This wasn't a problem before since we had only constants and we did the "right" thing, but now we are using symbolic values, we have to adjust for the types. What should be the semantics though? Let's say we want:
do we extend the first argument to 32 bits; do the shift, and chop it back? Or maybe reduce the second argument to 8 bits and do the shift? Something else? What if the shifted amount is larger than the shiftee? (Which I presume is actually more common.) I'd appreciate thoughts on this. |
I think the output size should match the size of the shifted input, and the index size should be coerced to match. If the index size is smaller it should be extended; if it is larger, it should be truncated, with the caveat that if any of the truncated bits are set, the result should be the appropriate saturated result (0 or -1 depending). I'm pretty sure this preserves the "perform n 1-bit shifts" semantics. |
Another alternative could be that we require shifted-amnt and shiftee to have the exact same bit-width, and let the caller of the library deal with adjusting them appropriately. I like the simplicity of that approach as it directly maps to SMT-Lib, and is also how we implement the If we did that, would that cause trouble on your end? |
Cryptol allows different sizes for the arguments, so we'll have to deal with that at some point, either inside SBV or outside. I feel like it is slightly nicer to do it inside the SBV abstraction boundary, especially as the SMTLib restriction to same-size arguments feels very arbitrary to me. |
Indeed; that restriction over there seems arbitrary.
Maybe we can have a compromise and say that the shift-amount is at-most as
big as the shifted value; otherwise we reject it? (And if it's smaller, we
pad it with zeros.) Is that reasonable?
…On Mon, Aug 7, 2017 at 6:32 PM, robdockins ***@***.***> wrote:
Cryptol allows different sizes for the arguments, so we'll have to deal
with that at some point, either inside SBV or outside.
I feel like it is slightly nicer to do it inside the SBV abstraction
boundary, especially as the SMTLib restriction to same-size arguments feels
very arbitrary to me.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#323 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAhiSRogF3nXKanCORt5JpjU5ESk9d7rks5sV7qtgaJpZM4Os7-e>
.
|
That could work... I'll still have to handle the other case on my end, but that's OK. However, I don't see how it makes your job any easier... do you have a typeclass already that statically compares the sizes of Word/Int types? |
No not really; I was planning to dynamically reject it. But now that I
think about it, I don't really like the idea. Both operands having the same
type might be a better choice here.
Let me give it some more thought; I'm not quite sure what the right thing
to do is yet.
…On Mon, Aug 7, 2017 at 6:41 PM, robdockins ***@***.***> wrote:
That could work... I'll still have to handle the other case on my end, but
that's OK.
However, I don't see how it makes your job any easier... do you have a
typeclass already that statically compares the sizes of Word/Int types?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#323 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAhiSTPbAhfhjC3GMFB7Q9bEi0LSIQIxks5sV7ywgaJpZM4Os7-e>
.
|
I remain concerned about the case where you are simply truncating the top bits of the index value. The semantics you have written down here will differ from the concrete execution semantics for cases where the top bits are set. Maybe the easiest way to handle this is to use an if statement to saturate the index amount? Something |
@robdockins Good point! Why I made those changes in the code base; can you review and give it a shot? |
Yes, you're right, The code looks sensible, I'll test it as soon as I get a chance. |
@robdockins I redid the implementation after that fix, which should be more robust/simpler. Do you mind doing a fresh pull and running your tests again? Thanks! |
The cryptol test suite is showing some failures that I think are related to these most recent changes, but I haven't tracked down the root cause yet. |
I just pushed in another commit: 675c401 to address the My test-suite is passing, can you do a fresh pull and let's see what's wrong.. |
Fresh pull results in a failing case; reverting to d4b8472 fixes the immediate problem. I'm still not sure what the problem is yet. |
one difference is that negative shifts are no longer well defined when you explicitly call Though I don't see why that should be an issue for Cryptol.. Curious. |
@robdockins any news on what the culprit might be? |
Sorry, not yet; I haven't had a chance to look into it more deeply yet. For reference, the Cryptol program demonstrating the problem is:
Using SBV prior to d4b8472 causes this property to QED when I attempt to When I look at the output SMTLib, it's clear that something is wrong (it doesn't mention a shift at all!), but I don't know why. Here is the SMT file created by new SBV for this proof:
And here it is prior to the most recent changes:
|
Looks like the entire definition of
there's neither a shift, nor the addition; which suggests The first step would be to replicate this purely using SBV, with no Cryptol involvement; I tried a few things but wasn't able to do so. I'll see if I can get something later tonight. |
@robdockins I see what the problem is. It's this line here: https://github.com/LeventErkok/sbv/blob/master/Data/SBV/Core/Operations.hs#L644 It's stuffing the bit-size of I didn't notice this in SBV because the "smallest" you have the shift is 8-bits, which is more than enough to put in the bit-width of the largest bit-vector of 64; and we never have this problem. I'll see if I can come up with a solution shortly.. |
…itting into bitsize of shift-amount Addresses #323
@robdockins Fix is in, give it a shot! |
That seems to fix the problem! Thanks! |
Cool. Do you need a release, or can this wait till we accumulate more changes. (I'm happy either way.) |
I think this can wait a bit. |
Great; closing this ticket then. Feel free to open a new ticket if anything else comes up. |
@robdockins sbv 7.2 is now released on Hackage which contains the fix for this issue. |
Consider the following GHCi interaction:
The
sShiftRight
operation is giving incorrect answers for shift values that exceed the number of bits in the word to be shifted. This appears to be due to the use ofsvSelect
in its implementation with a zero default.Is there a particular reason to implement right and left shifts using table lookups instead of relying on underlying primitives (
bvshl
,bvlshr
andbvashr
in SMTLib)?The text was updated successfully, but these errors were encountered: