Skip to content
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

Bug in some shift/rotates #1191

Closed
robdockins opened this issue May 5, 2021 · 2 comments · Fixed by #1192
Closed

Bug in some shift/rotates #1191

robdockins opened this issue May 5, 2021 · 2 comments · Fixed by #1192
Assignees
Labels
bug Something not working correctly

Comments

@robdockins
Copy link
Contributor

Consider the following:

xs : [32]
xs = 0xdeadbeef

f : [32] -> [32]
f zs = zs <<< ( [True,False,False]:[3] )

q0 = f xs
q1 = f (rnf (xs @@ [0..31]))
q2 = f      (xs @@ [0..31])

I expect q0, q1 and q2 to all compute the same answer. However, in current master, q2 computes the wrong value. The other shift and rotate operations are also broken in similar ways. Probably, the culprit is the code path that computes results when both arguments of a shift or rotate are unpacked bit vectors, as the example starts working correctly when either argument is packed.

@robdockins robdockins added the bug Something not working correctly label May 5, 2021
@robdockins robdockins self-assigned this May 5, 2021
@brianhuffman
Copy link
Contributor

brianhuffman commented May 5, 2021

I just added some putStrLns to the barrelShifter function to get some tracing output. It appears that the n parameter to the go inner function does not take the values 3, 2, 1 as you'd expect for a 3-bit shift amount, but rather it takes the values 32, 31, 30. If you change the type of xs in the example from [32] to [48] (for example) then n takes the values 48, 47, 46.

So it appears that the "number of bits in shift amount" parameter to barrelShifter is simply being passed the width of the number being shifted instead of the width of the shift amount.

I believe the bug is on this line:

bitmapWordVal sym n =<< barrelShifter sym (iteBit sym) shiftOp (Nat n) bs0 n idx_segs

The second-to-last argument, n is actually the width of the shifted array, when it should instead be the width of the index.

@robdockins
Copy link
Contributor Author

robdockins commented May 5, 2021

Yep, that looks like the likely culprit. I guess I should go through and audit all the uses of barrelShifter to make sure this mistake doesn't occur elsewhere too.

EDIT: fixing that line does indeed seem like it fixes the bug, and other uses of the barrel shifter are correctly using the number of index bits for that argument. I'll put together a patch, and take the opportunity to add some documentation to these functions while I'm in there.

robdockins added a commit that referenced this issue May 6, 2021
The barrel shifter was being called with the wrong width; the
length of the sequence to be shifted was passed instead of the number
of bits in the index word.
yav pushed a commit that referenced this issue May 26, 2021
The barrel shifter was being called with the wrong width; the
length of the sequence to be shifted was passed instead of the number
of bits in the index word.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something not working correctly
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants