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

Reply via email to