Bug#443576: gcc-4.2: -O2 generates wrong code
Package: gcc-4.2
Version: 4.2.1-5
Severity: critical
Justification: breaks unrelated software
Hello,
I think I found a bug in gcc-4.2. The bug is easy to reproduce. I have
it under sid and also under testing.
I provide a simple test program (gint_to_pointer.c):
#include <stdio.h>
int main(void)
{
int i, j;
for (i=0; i<6; i++)
{
j = i-1;
printf("%d %d\n", j, (void *)(j));
}
}
When compiled with make gint_to_pointer CFLAGS="-O0" the execution gives:
-1 -1
0 0
1 1
2 2
3 3
4 4
But when compiled with make gint_to_pointer CFLAGS="-O2" the execution gives:
-1 -1
0 -1
1 -1
2 -1
3 -1
4 -1
I generated the assembly for the two cases.
With -O0
.file "gint_to_pointer.c"
.section .rodata
.LC0:
.string "%d %d\n"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl $0, -12(%ebp)
jmp .L2
.L3:
movl -12(%ebp), %eax
subl $1, %eax
movl %eax, -8(%ebp)
movl -8(%ebp), %eax
movl %eax, 8(%esp)
movl -8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
addl $1, -12(%ebp)
.L2:
cmpl $5, -12(%ebp)
jle .L3
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.2.1 (Debian 4.2.1-5)"
.section .note.GNU-stack,"",@progbits
with -O2:
.file "gint_to_pointer.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d %d\n"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ebx
xorl %ebx, %ebx
pushl %ecx
subl $16, %esp
movl $-1, 8(%esp)
movl $-1, 4(%esp)
movl $.LC0, (%esp)
call printf
.p2align 4,,7
.L2:
movl %ebx, 4(%esp)
addl $1, %ebx
movl $-1, 8(%esp)
movl $.LC0, (%esp)
call printf
cmpl $5, %ebx
jne .L2
addl $16, %esp
popl %ecx
popl %ebx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.2.1 (Debian 4.2.1-5)"
.section .note.GNU-stack,"",@progbits
I do not read i386 assembly so can't help spot the bug.
Notes:
I have no problem if I use "i" or "i+1" instead of "i-1".
I have no problem if I start the loop at 1 instead of 0.
I discovered the bug because of my package does not work correctly anymore.
Other packages compiled with gcc-4.2 may also fail in very obscure ways.
Thanks,
-- System Information:
Debian Release: lenny/sid
APT prefers testing
APT policy: (500, 'testing'), (90, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.22-2-686 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages gcc-4.2 depends on:
ii binutils 2.18-1 The GNU assembler, linker and bina
ii cpp-4.2 4.2.1-5 The GNU C preprocessor
ii gcc-4.2-base 4.2.1-5 The GNU Compiler Collection (base
ii libc6 2.6.1-1+b1 GNU C Library: Shared libraries
ii libgcc1 1:4.2.1-5 GCC support library
ii libgomp1 4.2.1-5 GCC OpenMP (GOMP) support library
Versions of packages gcc-4.2 recommends:
ii libc6-dev 2.6.1-1+b1 GNU C Library: Development Librari
pn libmudflap0-4.2-dev <none> (no description available)
-- no debconf information
Reply to: