TESTCASE for powerpc misoptimization
Franz Sirl
Franz.Sirl-kernel@lauterbach.com
Sun May 24 07:59:00 GMT 1998
> In message < v03130305b18b4b44e3fc@[195.180.235.87] >you write:
> > Hi,
> >
> > on the linux-pmac list an optimization bug with egcs-1.0.3 was reported
> > (see original message below) with a testcase. I checked with the latest
> > CVS-egcs and the bug is still there. I massaged the testcase a little bit
> > for the gcc.dg directory.
> >
> > Jeff, what about the other testcase in my status report? Wasn't it fit for
> > checkin?
>I added this test after minor tweaks (only run it on the rs6000/ppc
>since some targets don't support pic).
Hi Jeff,
this test won't be executed on powerpc unless you change the target restriction
from ppc-* to powerpc-*.
It turns out the Linux kernel compilation bug (the "mknod" bug) is eventually
the same bug.
The appended testcase#1 produces the follwing correct code for -O2
-fno-expensive-optimizations:
int sys_mknod(const char * filename, int mode, dev_t dev)
{
1800570: 94 21 ff e0 stwu r1,-32(r1)
1800574: 7c 08 02 a6 mflr r0
1800578: 93 61 00 0c stw r27,12(r1)
180057c: 93 81 00 10 stw r28,16(r1)
1800580: 93 a1 00 14 stw r29,20(r1)
1800584: 93 c1 00 18 stw r30,24(r1)
1800588: 93 e1 00 1c stw r31,28(r1)
180058c: 90 01 00 24 stw r0,36(r1)
1800590: 7c 9b 23 78 mr r27,r4
1800594: 7c bd 2b 78 mr r29,r5
int error;
char * tmp;
tmp = getname(filename);
1800598: 4b ff ff 59 bl 18004f0 <getname>
180059c: 57 a5 70 12 rlwinm r5,r29,14,0,9
18005a0: 7c 7c 1b 78 mr r28,r3
18005a4: 57 bd 06 3e clrlwi r29,r29,24
error = ((long)( tmp )) ;
do_mknod(tmp,mode,to_kdev_t(dev));
18005a8: 7c a5 eb 78 or r5,r5,r29
18005ac: 7f 64 db 78 mr r4,r27
18005b0: 4b ff ff 15 bl 18004c4 <do_mknod>
The same testcase with -O2 produces this wrong code:
int sys_mknod(const char * filename, int mode, dev_t dev)
{
1800568: 94 21 ff e0 stwu r1,-32(r1)
180056c: 7c 08 02 a6 mflr r0
1800570: 93 61 00 0c stw r27,12(r1)
1800574: 93 81 00 10 stw r28,16(r1)
1800578: 93 a1 00 14 stw r29,20(r1)
180057c: 93 c1 00 18 stw r30,24(r1)
1800580: 93 e1 00 1c stw r31,28(r1)
1800584: 90 01 00 24 stw r0,36(r1)
1800588: 7c 9b 23 78 mr r27,r4
180058c: 7c bd 2b 78 mr r29,r5
int error;
char * tmp;
tmp = getname(filename);
1800590: 4b ff ff 61 bl 18004f0 <getname>
1800594: 7c 7c 1b 78 mr r28,r3
1800598: 57 bd 70 12 rlwinm r29,r29,14,0,9
error = ((long)( tmp )) ;
do_mknod(tmp,mode,to_kdev_t(dev));
180059c: 7f 64 db 78 mr r4,r27
18005a0: 53 a5 00 2e rlwimi r5,r29,0,0,23 <-------
18005a4: 4b ff ff 21 bl 18004c4 <do_mknod>
As you can see, the rlwimi instruction places r29 into the higher 24 bits of r5,
but r5 is clobbered in getname(), so the lower 8 bits of r5 contain wrong
values.
I additionally appended testcase#2 for the "needed new GOT during reload" bug,
which I already posted 2 times ;-).
Franz.
>----------------------------------
Testcase#1:
/* { dg-do run } */
/* { dg-options "-O2" } */
/*#include <stdio.h>*/
typedef unsigned int dev_t;
typedef unsigned int kdev_t;
static inline kdev_t to_kdev_t(int dev)
{
int major, minor;
if (sizeof(kdev_t) == 16)
return (kdev_t)dev;
major = (dev >> 8);
minor = (dev & 0xff);
return ((( major ) << 22 ) | ( minor )) ;
}
void do_mknod(const char * filename, int mode, kdev_t dev)
{
/* printf("%0x\n",dev);*/
if (dev==0x15800078)
exit(0);
else
abort();
}
char * getname(const char * filename)
{
register unsigned int a1,a2,a3,a4,a5,a6,a7,a8,a9;
a1 = (unsigned int)(filename) *5 + 1;
a2 = (unsigned int)(filename) *6 + 2;
a3 = (unsigned int)(filename) *7 + 3;
a4 = (unsigned int)(filename) *8 + 4;
a5 = (unsigned int)(filename) *9 + 5;
a6 = (unsigned int)(filename) *10 + 5;
a7 = (unsigned int)(filename) *11 + 5;
a8 = (unsigned int)(filename) *12 + 5;
a9 = (unsigned int)(filename) *13 + 5;
return (char *)(a1*a2+a3*a4+a5*a6+a7*a8+a9);
}
int sys_mknod(const char * filename, int mode, dev_t dev)
{
int error;
char * tmp;
tmp = getname(filename);
error = ((long)( tmp )) ;
do_mknod(tmp,mode,to_kdev_t(dev));
return error;
}
int main(void)
{
return sys_mknod("test",1,0x12345678);
}
>----------------------------------
Testcase#2:
/* { dg-do compile { target rs6000-*-*-* powerpc-*-*-* } } */
/* { dg-options "-O2 -fpic" } */
int
test(void)
{
double value, maxValue = - (__extension__ ((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) { __l: 0x7ff0000000000000ULL }).__d) ;
int idx, maxIdx = 1;
for (idx = 1; idx < 22; idx++) {
if (value > maxValue) {
maxValue = value;
maxIdx = idx;
}
}
return 0 ;
}
More information about the Gcc-bugs
mailing list