With code attached, say, sum.c, the output with -O2 shows different value with -O or -O1. -O sum = 0x68ac -O1 sum = 0x68ac -O2 sum = 0x8fb9 Release: 3.1.1 Environment: System: NetBSD quick 1.5ZC NetBSD 1.5ZC (GENERIC) #0: Fri Mar 29 19:38:39 JST 2002 tsubai@mahoro:/a/0328/src/sys/arch/macppc/compile/GENERIC macppc host: powerpc--netbsd build: powerpc--netbsd target: powerpc--netbsd configured with:../configure --with-gcc-version-trigger=/export/local-src/gcc-3.1.1/gcc/version.c --host=powerpc-unknown-netbsd1.5ZC --norecursion How-To-Repeat: Compile following file on macppc machine with -O1 and -O2 and execute them respectively. ------------------------------- #include <stdio.h> struct buf { int data; }; bug(m) struct buf *m; { int sum = 0; struct buf tmp; unsigned short *w = (void *)&tmp; bzero(&tmp, sizeof tmp); tmp.data = m->data; //asm volatile ("" ::: "memory"); sum += w[0]; sum += w[1]; printf("sum = 0x%x\n", sum); return 0; } main() { struct buf m; m.data = 0x12345678; bug(&m); } ------------------------------- I will attach the .s code for the reference: (1) with -O1 ......................................................................... .file "sum.c" .section .rodata .align 2 .LC0: .string "sum = 0x%x\n" .section ".text" .align 2 .globl bug .type bug,@function bug: stwu 1,-16(1) mflr 0 stw 0,20(1) lwz 0,0(3) stw 0,8(1) lhz 4,8(1) lhz 0,10(1) add 4,4,0 lis 3,.LC0@ha la 3,.LC0@l(3) crxor 6,6,6 bl printf li 3,0 lwz 0,20(1) mtlr 0 addi 1,1,16 blr .Lfe1: .size bug,.Lfe1-bug .align 2 .globl main .type main,@function main: stwu 1,-16(1) mflr 0 stw 0,20(1) lis 0,0x1234 ori 0,0,22136 stw 0,8(1) addi 3,1,8 crxor 6,6,6 bl bug lwz 0,20(1) mtlr 0 addi 1,1,16 blr .Lfe2: .size main,.Lfe2-main .ident "GCC: (GNU) 3.1.1" ......................................................................... (2) with -O2 ......................................................................... .file "sum.c" .section .rodata .align 2 .LC0: .string "sum = 0x%x\n" .section ".text" .align 2 .globl bug .type bug,@function bug: stwu 1,-16(1) mflr 0 stw 0,20(1) lhz 4,8(1) lhz 0,10(1) lwz 9,0(3) lis 3,.LC0@ha add 4,4,0 la 3,.LC0@l(3) stw 9,8(1) crxor 6,6,6 bl printf lwz 0,20(1) li 3,0 addi 1,1,16 mtlr 0 blr .Lfe1: .size bug,.Lfe1-bug .align 2 .globl main .type main,@function main: stwu 1,-16(1) mflr 0 stw 0,20(1) addi 3,1,8 lis 0,0x1234 ori 0,0,22136 stw 0,8(1) crxor 6,6,6 bl bug lwz 0,20(1) addi 1,1,16 mtlr 0 blr .Lfe2: .size main,.Lfe2-main .ident "GCC: (GNU) 3.1.1" .........................................................................
Fix: Not known at the moment.
From: Andrew Pinski <pinskia@physics.uc.edu> To: makoto@ki.nu Cc: gcc-gnats@gcc.gnu.org Subject: Re: optimization/7427: gcc-3.1.1 -O2 problem for checksum calculation (powerpc) Date: Sun, 28 Jul 2002 18:34:54 -0400 Not a bug in gcc, but a bug in your code because of C aliasing rules. Thanks, Andrew Pinski On Sunday, July 28, 2002, at 06:17 , makoto@ki.nu wrote: > > unsigned short *w = (void *)&tmp;
From: Andrew Pinski <pinskia@physics.uc.edu> To: Makoto Fujiwara <makoto@ki.nu> Cc: gcc-gnats@gcc.gnu.org Subject: Re: optimization/7427: gcc-3.1.1 -O2 problem for checksum calculation (powerpc) Date: Sun, 28 Jul 2002 21:38:09 -0400 C aliasing rules say that variables with two different types do not belong to the same alias set (except for char* and void*). The correct way to fix the problem is using an union: #include <stdio.h> struct buf { =A0 =A0 =A0 =A0 int data; }; union buf1 { struct buf buf1; unsigned short m[sizeof(struct buf)/sizeof(short)]; }; bug(m) =A0 =A0 =A0 =A0 struct buf *m; { =A0 =A0 =A0 =A0 int sum =3D 0; =A0 =A0 =A0 =A0 union buf1 w; =A0 =A0 =A0 =A0 bzero(&w.buf1, sizeof tmp); =A0 =A0 =A0 =A0 w.buf1 =3D m->data; =A0 =A0 =A0 =A0 sum +=3D w.m[0]; =A0 =A0 =A0 =A0 sum +=3D w.m[1]; =A0 =A0 =A0 =A0 printf("sum =3D 0x%x\n", sum); =A0 =A0 =A0 =A0 return 0; } main() { =A0 =A0 =A0 =A0 struct buf m; =A0 =A0 =A0 =A0 m.data =3D 0x12345678; =A0 =A0 =A0 =A0 bug(&m); } Thanks, Andrew Pinski
Responsible-Changed-From-To: unassigned->paolo Responsible-Changed-Why: Triaged.
State-Changed-From-To: open->closed State-Changed-Why: Andrew is right.
From: Makoto Fujiwara <makoto@ki.nu> To: Andrew Pinski <pinskia@physics.uc.edu> Cc: gcc-gnats@gcc.gnu.org Subject: Re: optimization/7427: gcc-3.1.1 -O2 problem for checksum calculation (powerpc) Date: Mon, 29 Jul 2002 10:14:59 +0900 Andrew Pinski> Not a bug in gcc, but a bug in your code because of C aliasing rules. Andrew Pinski> > unsigned short *w = (void *)&tmp; Thanks Andrew, for super quick response. (1) 'gcc -Wall' gave nothing on the line 12. Is this still right ? (2) I have changed the code little bit and .. I have modified (a) and modifed (b) for further evaluation. (a) got printf in between while (b) does not. Code (a) with printf gave me the right sum even with -O2, but (b) gave the wrong sum. Is this right behavior of optimization ? (a) low = 0x181 hi = 0x8e84 sum = 0x68ac (b) sum = 0x8fb9 ------ (a) ------ #include <stdio.h> struct buf { int data; }; bug(m) struct buf *m; { int sum = 0; struct buf tmp; unsigned short *w = (void *) &tmp; unsigned short low,hi; bzero(&tmp, sizeof tmp); tmp.data = m->data; //asm volatile ("" ::: "memory"); low = w[0]; hi = w[1]; printf("low = 0x%x\n", low); printf("hi = 0x%x\n", hi); sum += w[0]; sum += w[1]; printf("sum = 0x%x\n", sum); return 0; } main() { struct buf m; m.data = 0x12345678; bug(&m); } ----- (b) ------- #include <stdio.h> struct buf { int data; }; bug(m) struct buf *m; { int sum = 0; struct buf tmp; unsigned short *w = (void *) &tmp; unsigned short low,hi; bzero(&tmp, sizeof tmp); tmp.data = m->data; //asm volatile ("" ::: "memory"); low = w[0]; hi = w[1]; // printf("low = 0x%x\n", low); // printf("hi = 0x%x\n", hi); sum += w[0]; sum += w[1]; printf("sum = 0x%x\n", sum); return 0; } main() { struct buf m; m.data = 0x12345678; bug(&m); } ------------------ --- Makoto Fujiwara, Chiba, Japan, Narita Airport and Disneyland prefecture.