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
Add mask before truncating dereferenced bit pointers #9584
Conversation
Needs a new behavior test case please |
Note that this bug only manifests itself in debug mode on my machine. I suspect it might also be different on other architectures. In any case, i think that the extra mask operation justifies the potential future headaches. |
Oh and by the way, this may seem like an esoteric bug, but i hit it during stage 2 development. This struct: Lines 2147 to 2154 in 4c9d417
Is loaded here, causing an incorrect value for Lines 6430 to 6432 in 4c9d417
Which in turn fails this check if both pointers have a different binary value for Line 420 in 4c9d417
|
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.
Looks good to merge provided the tests pass. We should also file an LLVM bug report upstream.
626cfc4
to
944ff10
Compare
944ff10
to
b9bb06d
Compare
Also submitted as LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=51529 |
Brilliant, thank you for the LLVM bug! |
This was a workaround for an LLVM 12 bug which has been fixed in LLVM 13. This reverts commit 5cd1d42 but keeps the test case.
Loading the value of a non-power-of-2 int larger than 8 bits yields something as follows in stage 1:
Unfortunately, LLVM does not always clear the upper bits of the resulting value after the truncate, as is evident in this snippet:
Above program yields
17
, instead of the expected1
. Note that the many arguments are required to forceflag_b
to be placed on the stack, and the union is also required.Of course, the upper bits of the result of the truncate are undefined, which would be fine, if llvm didn't try to use them afterwards. With this patch, LLVM is explicitly instructed to generate a masking operation before the truncate. This is also what clang itself seems to do when naively translating above snippet to C.