From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 543 invoked by alias); 2 Apr 2010 09:46:36 -0000 Received: (qmail 404 invoked by uid 48); 2 Apr 2010 09:46:11 -0000 Date: Fri, 02 Apr 2010 09:46:00 -0000 Subject: [Bug c/43629] New: Struct to register optimization fails X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "julien dot etienne at gmail dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2010-04/txt/msg00187.txt.bz2 Hello, It seems that when a structure is 64bit large the optimizer uses a register to store it, but does not managed the initialization of the fields properly, leading to a wrong result at the end. Here is my test case: cat main.c struct A { short A1 ; short A2 ; int A3 ; }; extern void* bar(void); static struct A foo(void) __attribute__ ((noinline)); static struct A foo(void) { struct A result; void *pB; result.A1 = (short)0; result.A2 = (short)0; /* The next field is intentionally not initialized */ /* result.A3 = 0; */ pB = bar(); /* always return (void*)1 to highlight the bug */ if (pB == ((void *)0)) { /* Should never been triggered at run time */ result.A1 = (short)1; result.A2 = (short)2; result.A3 = 3; return result; } /* result.A1 should be (short)0 */ return result; } int main(){ struct A myA = foo(); return (int)myA.A1; /* should always return 0 by design */ } cat bar.c void* bar(void){ return (void*)1; } Compilation with -O0 works and the return status is 0 as expected: /projects/dsr/work/jetienne/softs/gcc-4.4.3/bin/gcc -O0 -Wall -c -o main.o main.c /projects/dsr/work/jetienne/softs/gcc-4.4.3/bin/gcc -O0 -Wall -c -o bar.o bar.c /projects/dsr/work/jetienne/softs/gcc-4.4.3/bin/gcc main.o bar.o -o main ./main echo $? 0 Compilation with -O1 works but the return status is 1 due to the bug: /projects/dsr/work/jetienne/softs/gcc-4.4.3/bin/gcc -O1 -Wall -c -o main.o main.c /projects/dsr/work/jetienne/softs/gcc-4.4.3/bin/gcc -O1 -Wall -c -o bar.o bar.c /projects/dsr/work/jetienne/softs/gcc-4.4.3/bin/gcc main.o bar.o -o main ./main echo $? 1 As the code is deterministic the result should have been 0 in both cases. The disassembly of main.o file makes it pretty clear that the generated optimized code is wrong: objdump -d main.o main.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 : 0: 48 83 ec 08 sub $0x8,%rsp 4: e8 00 00 00 00 callq 9 9: 48 b8 01 00 02 00 03 mov $0x300020001,%rax <<< Value always returned 10: 00 00 00 13: 48 83 c4 08 add $0x8,%rsp 17: c3 retq 0000000000000018
: 18: 48 83 ec 08 sub $0x8,%rsp 1c: e8 df ff ff ff callq 0 21: 98 cwtl 22: 48 83 c4 08 add $0x8,%rsp 26: c3 retq As you can see in all cases the returned value of function foo is set by "mov $0x300020001,%rax" whereas there should also be 2 cases. My gcc version: /projects/dsr/work/jetienne/softs/gcc-4.4.3/bin/gcc -v Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ./configure --prefix=/projects/dsr/work/jetienne/softs/gcc-4.4.3 --enable-languages=c,c++ --with-mpfr=/tools/mpfr-2.4.2 Thread model: posix gcc version 4.4.3 (GCC) FYI I tried several gcc versions, here are the status: - gcc 3.4.5 works - gcc 4.1.2 works - gcc 4.3.2 does not work - gcc 4.4.3 does not work I am testing the svn trunk at the moment I will get back to you with my result. Best Regards, Julien -- Summary: Struct to register optimization fails Product: gcc Version: 4.4.3 Status: UNCONFIRMED Severity: blocker Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: julien dot etienne at gmail dot com GCC build triplet: x86_64-suse-linux GCC host triplet: x86_64-suse-linux GCC target triplet: x86_64-suse-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43629