-
Notifications
You must be signed in to change notification settings - Fork 7
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
Deal properly with undefined bits #1554
Conversation
Previously we checked `i1`s for guards using `cmp` i.e. we compared bytes instead of bits, breaking the "the upper bits are undefined" invariant. This commit does two things: 1. It changes the parts related to icmp to make clear that we've only tested the 8/16/32/64 bit cases. In particular, I'm not sure if the 1..=7 cases were, previously, broken or not. Since we don't seem to encounter them I'd rather `todo` them than try and think about them now. 2. It changes guard generation to use `bt` rather than `cmp` i.e. we only check the top bit instead of a whole byte.
This means that we should use `bt`, not `cmp`. Update the well-formedness checker to enforce this, which also uncovered a broken test.
About the first commit:
Suppose we have two And let's assume that these values are stored in registers and the registers contain What the current codegen will do is sign or zero extend (depending on the signedness of the operation) the n-bit values (here n=1) up to a 64-bit value. This is done with In this example All this to say: I disagree that the current code breaks the "the upper bits are undefined" invariant. It works by ensuring the undefined bits are defined before doing the 64-bit comparison. Or at least that was the intention when I wrote this code. Have I missed something? I do agree that special casing |
Actually, notice that |
I'm happy with the first commit if we can remove the part in the commit message saying that the code was invalidating the undefinedness guarantees. I think my explanation above shows that the codegen is actually quite careful to ensure that it isn't invalidated. |
Hang on, we raced. |
OK, now we are getting somewhere. It looks like |
@@ -2492,8 +2492,16 @@ impl<'a> Assemble<'a> { | |||
RegConstraint::Input(inst.falseval(self.m)), | |||
], | |||
); | |||
dynasm!(self.asm ; cmp Rb(cond_reg.code()), 0); |
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.
I agree that this one is comparing undefined bits too!
In summary:
|
This PR fixes two cases where we checked whole bytes, instead of a single bit, in generated code.