https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86673
Bug ID: 86673 Summary: inline asm sometimes ignores 'register asm("reg")' declarations Product: gcc Version: 8.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: arnd at linaro dot org Target Milestone: --- Created attachment 44438 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44438&action=edit linux/net/core/scm.o, preprocessed Building older linux kernels for ARM with a gcc-8.1 compiler has triggered a check for broken compiler versions, which compares the register number that is used in an inline assembly statement with the expected value, for an argument that was declared with the 'register foo asm ("reg")' syntax described in the gcc manual under "Specifying Registers for Local Variables". The diagnostic from the assembler is $ arm-linux-gnueabi-gcc -Wall -O2 scm.i -c -Wno-pointer-sign -fno-strict-aliasing /tmp/ccCGMQmS.s:648: Error: .err encountered /tmp/ccCGMQmS.s:679: Error: .err encountered Unfortunately, a change made to the kernel a few years ago had made this go unnoticed as everyone was testing gcc-8.1 only on more recent kernels that did not run into the particular check, but may have run into the bug without triggering the check. Architectures other than arm may also be affected, but nothing else has this check. I tested gcc-8.1.0 and today's gcc-8.1.1 (r262956), both with the same result. I attached one of the files that showed the problem, and reduced this using creduce to: int a, c, d, e; long b; void fn1() { int f = ({ ({ long g = b, j = g; register const typeof(c) h asm("r2") = 1, i = d; __asm__(".ifnc %2,r2; .err; .endif\n\t" "bl __put_user_4" : "=&r"(e) : ""(i), ""(h), ""(j)); e; }); }); a = f; }