https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90817
Bug ID: 90817 Summary: i386 inline assembly invalid register emitted Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: michaelrasmussen1337 at gmail dot com Target Milestone: --- Created attachment 46473 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46473&action=edit source, compiler output Under certain conditions GCC will emit invalid assembly code referencing 64-bit only registers in 32-bit mode. A reduced example is: int a, b; void f() { char c; for (;;) { __asm__ __volatile__("mov 0, %0\n\t" : "=r"(c) : "r"(0), "r"(256), "r"(a), "r"(b)); } } which (when compiled with -m32 -O1) ends up producing: mov 0, %sil with all versions of GCC I've tested (most of those available on https://gcc.godbolt.org/ (*) as well as the latest GCC versions available on 32- and 64-bit debian) except GCC 4.1.2. FWIW clang doesn't seem to have a problem with the code. I realize I've brought this issue upon myself by using inline assembly and it should be fixed by constraining "c" correctly ("Q" works here I think), but it still seems like a bug to me that an invalid register (in 32-bit mode) can be emitted. This wouldn't be too much of an issue except it's very hard to localize the source of the error since it's very sensitive to code structure and optimizations and ends up being reported at the end of the function. It would be nice if: * At the very least an ICE is reported before emitting an unusable register * An (local) error is emitted saying that the constraints of the inline assembly code could not be satisfied otherwise * Ideally an appropriate registers for an 8-bit variables is allocated (if possible) If somebody can point me in the right direction I don't mind taking a look myself. Attached is compiler input/ouput and the result of running gcc -v -save-temps ... (*): 9.1.0 being the latest, output is from 8.3.0