[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#484784: gcc-4.3: -O2 -O3 - wrong arguments are passing to inlined body of function



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



Reply to: