I have an optimization bug with gcc 3.4.3 on AMD64. If I use either O1, O2 or O3 then it fails. Only O0 works fine. I found a small workaround which works for any optimization level, it suffices to add a call to printf("..") for a particular local variable but of course this is not acceptable. I'm not in a position to test if it is a AMD64 specific problem or not.
Here is the output regarding the command line I'm using: gcc -v -g -c -O3 -Wall -pedantic -std=gnu99 -pipe -fPIC -c my_file.c Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.2/specs Configured with: ../configure --prefix=/usr --mandir=/usr/share/man -- infodir=/usr/share/info --enable-shared --enable-threads=posix --disable- checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind- exceptions --enable-languages=c,c++,objc,java,f77 --enable-java-awt=gtk -- host=x86_64-redhat-linux Thread model: posix gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3) /usr/libexec/gcc/x86_64-redhat-linux/3.4.2/cc1 -quiet -v my_file.c -quiet - dumpbase my_file.c -mtune=k8 -auxbase my_file -g -O3 -Wall -pedantic - std=gnu99 -version -fPIC -o - | as -V -Qy -o my_file.o - ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat- linux/3.4.2/../../../../x86_64-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /usr/lib/gcc/x86_64-redhat-linux/3.4.2/include /usr/include End of search list. GNU C version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3) (x86_64-redhat-linux) compiled by GNU C version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3). GGC heuristics: --param ggc-min-expand=98 --param ggc-min-heapsize=128172 GNU assembler version 2.15.92.0.2 (x86_64-redhat-linux) using BFD version 2.15.92.0.2 20040927 I've attached below the .s output of an extract of the routine which fails (i.e. without printf): .globl buggy_feature .type buggy_feature, @function buggy_feature: .LFB114: pushq %r12 .LCFI94: movl $1, %esi pushq %rbp .LCFI95: pushq %rbx .LCFI96: movl %edi, %ebx subq $32, %rsp .LCFI97: leaq 30(%rsp), %rdi call [EMAIL PROTECTED] movswl 30(%rsp),%edi xorl %edx, %edx xorl %esi, %esi incl %edi movslq %edi,%rdi call [EMAIL PROTECTED] testq %rax, %rax movq %rax, %rbp je .L1012 .L985: movswq 30(%rsp),%rsi movq %rbp, %rdi call [EMAIL PROTECTED] movswq 30(%rsp),%rdx movq [EMAIL PROTECTED](%rip), %rax movb $0, (%rdx,%rbp) cmpb $13, (%rax) jg .L1013 movl $0, 24(%rsp) .L987: leaq 22(%rsp), %rdi movl $1, %esi call [EMAIL PROTECTED] leaq 20(%rsp), %rdi movl $1, %esi call [EMAIL PROTECTED] movq type_array(%rip), %rcx movswq 22(%rsp),%r11 movslq %ebx,%r9 leaq (%r9,%r9,4), %r8 movq (%rcx), %r10 movq 8(%rcx), %rsi movw %bx, (%r10,%r11,2) leaq (%rsi,%r8,8), %rbx cmpw $-2, 28(%rbx) jne .L1014 Now the same code with an additional call to printf: .globl buggy_feature .type buggy_feature, @function buggy_feature: .LFB114: pushq %r12 .LCFI94: movl %edi, %r12d movl $1, %esi pushq %rbp .LCFI95: pushq %rbx .LCFI96: subq $32, %rsp .LCFI97: leaq 30(%rsp), %rdi call [EMAIL PROTECTED] movswl 30(%rsp),%edi xorl %edx, %edx xorl %esi, %esi incl %edi movslq %edi,%rdi call [EMAIL PROTECTED] testq %rax, %rax movq %rax, %rbp je .L1012 .L985: movswq 30(%rsp),%rsi movq %rbp, %rdi call [EMAIL PROTECTED] movswq 30(%rsp),%rdx movq [EMAIL PROTECTED](%rip), %rax movb $0, (%rdx,%rbp) cmpb $13, (%rax) jg .L1013 movl $0, 24(%rsp) .L987: leaq 22(%rsp), %rdi movl $1, %esi movslq %r12d,%rbx call [EMAIL PROTECTED] leaq 20(%rsp), %rdi movl $1, %esi call [EMAIL PROTECTED] movq type_array(%rip), %rcx movswq 22(%rsp),%r10 leaq (%rbx,%rbx,4), %r8 leaq .LC31(%rip), %rdi xorl %eax, %eax movq 8(%rcx), %rsi movq (%rcx), %r9 leaq (%rsi,%r8,8), %rbx movw %r12w, (%r9,%r10,2) movl %r12d, %esi call [EMAIL PROTECTED] cmpw $-2, 28(%rbx) jne .L1014 In both cases .L1014 is defined as: .L1014: xorl %edi, %edi call [EMAIL PROTECTED] The actual C code of the `buggy_feature' routine is: rt_public void buggy_feature (int type_index) { char *a_name; type_descriptor *a_conv; int16 nb_gen, num_attrib, name_length, dtype; int32 flags; read_int16 (&name_length, 1); a_name = (char *) eif_rt_xmalloc (name_length + 1, C_T, GC_OFF); if (a_name == NULL) xraise (EN_MEM); read_char (a_name, name_length); a_name[name_length] = '\0'; if (rt_kind_version >= 0x0E) { read_int32 (&flags, 1); } else { flags = 0; } read_int16 (&dtype, 1); read_int16 (&nb_gen, 1); type_array->type_index[dtype] = type_index; a_conv = type_array->descriptions + type_index; // Uncomment this line to ensure the condition below is not satisfied. // printf ("%d\n", type_index); if (!((a_conv->new_type == TYPE_UNDEFINED))) { exit(0); } } If you comment the `printf' line then the code calls `exit (0)', if you uncomment it, then it does not call it. It looks to me that the value of the `rbx' register is incorrect when there is no `printf' statement. Let me know if you need more information. Thanks, Manu -- Summary: Strange optimization issue Product: gcc Version: 3.4.2 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: manus at eiffel dot com CC: gcc-bugs at gcc dot gnu dot org GCC host triplet: Linux madrid.ise 2.6.9-1.667 #1 Tue Nov 2 14:50:10 EST 2004 x86_ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18616