[Bug inline-asm/56148] [4.8 Regression] inline asm matching constraint with different mode
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56148 Frank Mehnert fm3 at os dot inf.tu-dresden.de changed: What|Removed |Added CC||fm3 at os dot ||inf.tu-dresden.de --- Comment #14 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-02-22 14:39:44 UTC --- (In reply to comment #0) void foo (void) { unsigned char e[16]; unsigned long a, b, c, d; __asm__ __volatile__ ( : =d (a), =c (c), =D (d), =a (b) : 0 (-1U), mr (e), 1 (128 5), 2 (e), 3 (-1U)); } is rejected since LRA merge on x86_64-linux at -O2: rh905862.i: In function ‘foo’: rh905862.i:6:3: error: ‘asm’ operand has impossible constraints __asm__ __volatile__ ( : =d (a), =c (c), =D (d), =a (b) ^ The testcase is questionable, because a, c and b are DImode, while -1U, 128 5 and -1U are all SImode using 0/1/3 constraints matching those DImodes. But we accept it with reload or with -O0 even with LRA. Glad that gcc-4.8 does now behave as before but I would also like to understand what is questionable about this testcase. How to improve it?
[Bug target/55940] [4.7 Regression] Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 --- Comment #15 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-01-16 09:01:02 UTC --- Great, thank you Jakub! As it will take some time until the Linux distributions will update their gcc binaries to include this fix, do you have any suggestion how to work around this bug by changing the code? Omitting compiler switches on the command line will not work in our scenario as the Linux kernel Makefiles define the gcc command line parameters. And can you confirm that this bug only affects 32-bit x86 targets or does it affect 64-bit x86 targets as well?
[Bug target/55940] Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 --- Comment #4 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-01-15 13:53:04 UTC --- The problem is that I cannot reproduce this problem either. Some versions of gcc 4.7 might be affected (the affected user uses 'Exherbo gcc-4.7.2-r2'), others not. As far as I can tell, only Intel 32-bit code is affected. Regarding -mrtd: I don't know if this command line parameter is used at all. I've just asked the affected user for the complete command line. But a function with 'cdecl,regparm(0)' should pass all parameters on the stack on 32-bit x86 machines, right? And even if some parameters are passed in registers, EDI is normally not used, only EAX, EDX or ECX but never EDI.
[Bug target/55940] Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 --- Comment #5 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-01-15 15:03:14 UTC --- Actually I was able to reproduce generating the buggy code. My gcc version: Using built-in specs. COLLECT_GCC=/usr/bin/gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.7.2 (Debian 4.7.2-5) I used the memobj-r0drv.i file from the above ticket and used the following command line: gcc -Os -m32 -c -o memobj-r0drv.o memobj-r0drv.i -mpreferred-stack-boundary=2 The -mpreferred-stack-boundary=2 is essential! Using this command line, the same wrong code is generated (parameter is assumed to be passed in the EDI register).
[Bug target/55940] Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 --- Comment #7 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-01-15 15:37:43 UTC --- Actually this looks like some mixup in the generated machine code: VBoxHost_RTR0MemObjGetPagePhysAddr(): c1b: 8b 0f mov(%edi),%ecx c1d: 8b 47 04mov0x4(%edi),%eax c20: 8d 91 00 10 00 00 lea0x1000(%ecx),%edx c26: 81 fa ff 1f 00 00 cmp$0x1fff,%edx c2c: 76 49 jbec77 VBoxHost_RTR0MemObjGetPagePhysAddr+0x5c c2e: 81 39 10 12 61 19 cmpl $0x19611210,(%ecx) c34: 75 41 jnec77 VBoxHost_RTR0MemObjGetPagePhysAddr+0x5c c36: 55 push %ebp c37: 89 e5 mov%esp,%ebp c39: 57 push %edi c3a: 53 push %ebx c3b: 8b 51 08mov0x8(%ecx),%edx c3e: 8d 7d 08lea0x8(%ebp),%edi c41: 8d 5a fflea-0x1(%edx),%ebx c44: 83 fb 07cmp$0x7,%ebx c47: 77 34 ja c7d VBoxHost_RTR0MemObjGetPagePhysAddr+0x62 The EDI register is loaded from stack later and the two lines at 0xc1b and 0xc1d just access the EDI register before it is properly initialized.
[Bug target/55940] Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 --- Comment #8 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-01-15 16:54:53 UTC --- Created attachment 29172 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=29172 Preprocessed source
[Bug target/55940] Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 --- Comment #9 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-01-15 16:55:40 UTC --- Just added the preprocessed source, sorry for the delay. It's the source code from the VirtualBox ticket.
[Bug target/55940] Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 --- Comment #10 from Frank Mehnert fm3 at os dot inf.tu-dresden.de 2013-01-15 16:57:48 UTC --- And regarding your comment, Jakub, in this case it's not a question of not emitting the code of a function or not. The function code is emitted and the code is definitely wrong. EDI was not initialized before it was used.
[Bug target/55940] New: Incorrect code for accessing parameters with 32-bit Intel hosts
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55940 Bug #: 55940 Summary: Incorrect code for accessing parameters with 32-bit Intel hosts Classification: Unclassified Product: gcc Version: 4.7.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: f...@os.inf.tu-dresden.de There are some reports about incorrect compiled Linux kernel modules for VirtualBox. I've debugged one report (see here: https://www.virtualbox.org/ticket/11035) and saw that the compiler generated invalid code for accessing parameters inside a function. When it should read the parameter from the stack it reads the parameter from a register. I don't know exactly under which circumstance this happens but this seems to be related to 32-bit x86 targets. The function VBoxHost_RTR0MemObjGetPagePhysAddr is marked as __attribute__((cdelc, regparm(0))). The pre-processed memobj-r0drv.i file is attached to that ticket. The generated code is part of the vboxdrv.ko file which is also attached to the ticket. The following code is generated to access the first function parameter (keep cdecl in mind!): VBoxHost_RTR0MemObjGetPagePhysAddr(): /usr/src/virtualbox-bin-4.2.4_81684/vboxhost/vboxdrv/r0drv/memobj-r0drv.c:268 955e: 8b 0f mov(%edi),%ecx 9560: 8b 47 04mov0x4(%edi),%eax /usr/src/virtualbox-bin-4.2.4_81684/vboxhost/vboxdrv/r0drv/memobj-r0drv.c:272 9563: 8d 91 00 10 00 00 lea0x1000(%ecx),%edx So the function is using the EDI register to access the parameter while it should read the parameter from the stack. The C code of this function looks (see memobj-r0drv.i) is: RTHCPHYS __attribute__((cdecl,regparm(0))) VBoxHost_RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage) { PRTR0MEMOBJINTERNAL pMem; size_t cPages; do { if (__builtin_expect(!!(!(( (uintptr_t)(MemObj) + 0x1000U = 0x2000U ))), 0)) return ((~(RTHCPHYS)0)); } while (0); ... (Explanation of the code: This is actually a sanity check if the pointer is valid; the value must be either less than 0xF000U or greater than 0x0FFFU). Unfortunately I cannot reproduce this problem myself (gcc 4.7.2 on my Linux distribution creates correct code). The gcc compiler the user is using is gcc version 4.7.2 (Exherbo gcc-4.7.2-r2) (see comment 18 in the above ticket).