--- Begin Message ---
Subject: gcc-4.3: -O2 -O3 - wrong arguments are passing to inlined body of function
Package: gcc-4.3
Version: 4.3.0-5
Severity: important
Consider this simple program:
---bug.c---
#define N 100
char array[N];
void inline_asm(int iters) {
__asm__ volatile (
#ifdef PRESERVE_ALL_REGS
"pushal \n"
#endif
" xorl %%ebx, %%ebx \n"
"0: \n"
" movzbl (%%eax), %%edx \n"
" addl %%edx, %%ebx \n"
" incl %%eax \n"
" decl %%ecx \n"
" jnz 0b \n"
#ifdef PRESERVE_ALL_REGS
"popal \n"
#endif
: /* no output */
: "a" (array),
"c" (iters)
: "ebx", "edx"
);
}
int main() {
int n = 100;
while (n--)
inline_asm(N);
}
---eof---
Function inline_asm just add all values from array; all modified/input
registers are listed in __asm__ statement.
When program is compiled without any optimization flag, it works ok.
However if compiled with -O3 or -O3 --- segfaults. I quickly analyzed
assembly output, and it is clear, that gcc fully inlined procedure,
however in a while loop only address is restored (%eax), but inner loop
counter (%ecx) isn't. Thus in a second iteration %ecx has value 0, and
loop would execute 0xffffffff times, but segfault appear faster.
When sample program is compiled with -O3 -DPRESERVE_ALL_REGS all is
ok, because pair pushal/popal saves and restores all registers.
---bug.s---
main:
# .. snip ...
movl $array, %esi
pushl %ebx
pushl %ecx
movl $100, %ecx <-- ERROR: ecx is loaded only once
.p2align 4,,7
.p2align 3
#while
.L4:
movl %esi, %eax <-- OK: eax is reloaded in every while-iteration
#APP
# 6 "bug.c" 1
xorl %ebx, %ebx
0:
movzbl (%eax), %edx
addl %edx, %ebx
incl %eax
decl %ecx
jnz 0b
# 0 "" 2
#NO_APP
addl $1, %edi
cmpl $100, %edi
jne .L4
#endwhile
# ... snip ...
---cut---
-- System Information:
Debian Release: lenny/sid
APT prefers unstable
APT policy: (500, 'unstable'), (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 2.6.25-2-686 (SMP w/2 CPU cores)
Locale: LANG=pl_PL, LC_CTYPE=pl_PL (charmap=ISO-8859-2)
Shell: /bin/sh linked to /bin/bash
Versions of packages gcc-4.3 depends on:
ii binutils 2.18.1~cvs20080103-6 The GNU assembler, linker and bina
ii cpp-4.3 4.3.0-5 The GNU C preprocessor
ii gcc-4.3-base 4.3.0-5 The GNU Compiler Collection (base
ii libc6 2.7-12 GNU C Library: Shared libraries
ii libgcc1 1:4.3.0-5 GCC support library
ii libgomp1 4.3.0-5 GCC OpenMP (GOMP) support library
Versions of packages gcc-4.3 recommends:
ii libc6-dev 2.7-12 GNU C Library: Development Librari
--- End Message ---