-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Incorrect assembly emitted for cmpxchg IR instruction on thumbv7m-none-eabi target #38176
Comments
The issue appears to be that t2LDREX is being produced with an (offset) FrameIndex operand, but it is marked as AddrModeNone in the .td file. rewriteFrameIndex does not expect this and asserts in a Debug build. Incorrect code is emitted in a release build. The options for fixing it are:
The first one seems like the highest quality solution. |
As far as I can tell, this should only affect t2addrmode_imm0_1020s4, which is only used by t2LDREX and t2STREX . I would prefer to just take the simple fix of changing SelectT2AddrModeExclusive so it doesn't try to special-case frame indexes, since that path clearly hasn't been tested. If someone cares, we can try to optimize later, but it's unlikely to matter much. |
I'd still prefer to do the right thing. An unused addressing mode is offensive to me. I'll see what I can come up with tomorrow. After all, it looks like I added the bug back in 2013. |
I've posted a patch for review at https://reviews.llvm.org/D51678. |
Based on the comments it seems this was fixed in 341642. |
Extended Description
When compiled with:
clang -c -target thumbv7m-none-eabi -O1 compare_exchange.c
The attached C program produces invalid assembly code that attempts to load a value from outside the function's stack frame in the first "ldrex" instruction of the compare exchange operation. The rest of the stack access generated by the cmpxchg seem to be correct. More weird results can be obtained by adding/removing "int"s before the atomic one. I've also attached the generated assembly and IR code from my machine.
The problem seems to be on the assembly generation level and not in clang itself (I ran into this while using Rust). The example program uses intrinsics instead of standard C to make sure it's not a header issue, but the same problem happens with stdatomic.h.
Compiling with "-target thumbv7-none-eabi" instead seems to produce correct code, as well as compiling with -O0.
LLVM version: Tip of trunk from SVN, as well as 6.0.0-1ubuntu2 (my machine, from the official Ubuntu repositories)
Godbolt link for quick verification:
https://godbolt.org/z/Ozr2xa
The text was updated successfully, but these errors were encountered: