[Bug c/43629] New: Struct to register optimization fails
julien dot etienne at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Apr 2 09:46:00 GMT 2010
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 <foo>:
0: 48 83 ec 08 sub $0x8,%rsp
4: e8 00 00 00 00 callq 9 <foo+0x9>
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 <main>:
18: 48 83 ec 08 sub $0x8,%rsp
1c: e8 df ff ff ff callq 0 <foo>
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
More information about the Gcc-bugs
mailing list