This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

TESTCASE for powerpc misoptimization


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?

Franz.

testcase:
/* { dg-do run } */
/* { dg-options "-O2 -fpic" } */

void foo1(int a, char *b, int c)
{
   c =a+c+234;
}

int foo2(int d)
{
   return d*d;
}

int bar1, bar2, bar3;
char * bar4;

int main(void) {
    int h;
    bar1 = foo2(1);
    bar2 = foo2(1);

    h = foo2(1);
    foo1(1, "a", foo2(1));
    foo1(bar1, "a", foo2(1));
    foo2(1);

    h = foo2(1);
    bar3 = 1;
    bar4 = "a";
    foo1(1, "n", foo2(1));
    foo1(1, "o", foo2(1));
    foo1(1, "p", foo2(1));
    foo1(bar1, "a", foo2(1));

    bar3 = h;
    bar4 = "b";  foo1(bar1, "b", foo2(1));
    foo1(1, "q", foo2(1));
    bar4 = "c";  foo1(1, "c", foo2(1));
    bar4 = "d";  foo1(1, "d", foo2(1));
    bar4 = "e";  foo1(1, "e", foo2(1));
    bar4 = "f";  foo1(1, "f", foo2(1));
    bar4 = "g";  foo1(1, "g", foo2(1));
    bar4 = "h";  foo1(1, "h", foo2(1));
    bar4 = "i";  foo1(1, "i", foo2(1));
    bar4 = "j";  foo1(1, "j", foo2(1));
    bar4 = "k";  foo1(1, "k", foo2(1));
    bar4 = "l";  foo1(1, "l", foo2(1));
    bar4 = "m";
    foo1(bar2, "m", foo2(1));
    exit(0);
}



warner@lothar.com wrote:
>Ok, I've got a weird one for you folks. I'm seeing a bug in the -fpic
>optimizer under egcs. The result of the bug is a crash during startup of the
>perl5 Gtk module because the register used to point to the GOT is mistakenly
>used to hold an intermediate result too early, trashing the GOT pointer which
>is then used to look up another global and segfaults.
>
>First, my environment:
> linux-pmac on a PowerCenterPro
> kernel is from the vger CVS archive, up-to-date as of mid May.
> egcs-1.0-2e installed from ftp.linuxppc.org RPM (latest available RPM)
> binutils-2.9.1-1a also from RPM (latest available RPM)
>
>compile the following with
>  gcc -c -g -O2 -fpic foo.c
>then disassemble with
>  objdump -d --source --reloc foo.o >foo.dis
>       ------ begin -------
>void foo1(int, char *, int);
>int foo2(int);
>int bar1, bar2, bar3;
>char * bar4;
>
>void initPerlGdkDefs(void) {
>    int h;
>    bar1 = foo2(1);
>    bar2 = foo2(1);
>
>    h = foo2(1);
>    foo1(1, "a", foo2(1));
>    foo1(bar1, "a", foo2(1));
>    foo2(1);
>
>    h = foo2(1);
>    bar3 = 1;
>    bar4 = "a";
>    foo1(1, "n", foo2(1));
>    foo1(1, "o", foo2(1));
>    foo1(1, "p", foo2(1));
>    foo1(bar1, "a", foo2(1));
>
>    bar3 = h;
>    bar4 = "b";  foo1(bar1, "b", foo2(1));
>    foo1(1, "q", foo2(1));
>    bar4 = "c";  foo1(1, "c", foo2(1));
>    bar4 = "d";  foo1(1, "d", foo2(1));
>    bar4 = "e";  foo1(1, "e", foo2(1));
>    bar4 = "f";  foo1(1, "f", foo2(1));
>    bar4 = "g";  foo1(1, "g", foo2(1));
>    bar4 = "h";  foo1(1, "h", foo2(1));
>    bar4 = "i";  foo1(1, "i", foo2(1));
>    bar4 = "j";  foo1(1, "j", foo2(1));
>    bar4 = "k";  foo1(1, "k", foo2(1));
>    bar4 = "l";  foo1(1, "l", foo2(1));
>    bar4 = "m";
>    foo1(bar2, "m", foo2(1));
>}
>     ------ end ------
>
>I apologize for the contrived example, and for its length, but removing any
>statements at all results in the bug going away. The function used to be the
>initPerlGdkDefs() function of the GtkDefs.c file of the Gtk-0.2.1 perl5
>module,
>but is barely recognizable now.
>
>The bug is the following: if you look at the disassembled output, near the
>end:
>    foo1(bar2, "m", foo2(1));
> 2d4:	38 60 00 01 	li	r3,1
> 2d8:	91 3b 00 00 	stw	r9,0(r27)
> 2dc:	81 3d 00 00 	lwz	r9,0(r29)
>			2de: R_PPC_GOT16	bar2
> 2e0:	83 a9 00 00 	lwz	r29,0(r9)
> 2e4:	48 00 00 01 	bl	2e4 <initPerlGdkDefs+0x2e4>
>			2e4: R_PPC_PLTREL24	foo2
> 2e8:	81 3d 00 00 	lwz	r9,0(r29)
>			2ea: R_PPC_GOT16	.LC17
> 2ec:	7c 65 1b 78 	mr	r5,r3
> 2f0:	80 89 00 00 	lwz	r4,0(r9)
> 2f4:	7f a3 eb 78 	mr	r3,r29
> 2f8:	48 00 00 01 	bl	2f8 <initPerlGdkDefs+0x2f8>
>			2f8: R_PPC_PLTREL24	foo1
>
>
>>From what I can tell, you get at some symbol in the GOT by doing a series of:
>   lwz temp, GOT_OFFSET(r29)
>   lwz dest, 0(temp)
>It looks like r29 holds the GOT pointer, and r9 is used as the temporary to do
>the dereference necessary to put the "m" string constant into r4. But at 2e0,
>r29 gets clobbered to hold 'bar2' in anticipation of transferring it into
>r3 at
>2f4. So the statement at 2e8 gets a segfault as we dereference 'bar2' plus
>some offset that should have pointed into the GOT table.
>
>In trying to minimize the test case, I discovered that it is strongly
>dependent upon having enough code in the middle of the function (removing any
>of the mostly identical 'bar4 = "c"; foo1(1, "c", foo2(1));' lines made the
>problem go away), and it depends upon the string constants in those middle
>lines being the same (perhaps it is merging identical strings into one,
>allowing the pointer to be re-used without a second GOT lookup but then
>requiring a spare register to hold that pointer across the foo2()
>calls?). Basically any way I shortened or modified the function from where it
>is now makes the problem go away. Compiling with -fPIC instead of -fpic makes
>the problem go away. -O1 instead of -O2 makes it go away, but turning off
>debugging doesn't seem to affect it.
>
>The number of lines necessary to trigger the bug makes me think that a
>register
>is getting allocated for each line, and the GOT table pointer is not getting
>protected from this allocation and gets clobbered.
>
>Does this help anyone? I'd be happy to try this against newer egcs versions,
>(especially if they came in RPM packages that were easy to back out..).
>Obviously I can just compile it -O1 and get a working module, but I thought
>that a real test case might be useful to the compiler wizards out there.
>
>Hope this does something for somebody,
> -Brian
>   warner@lothar.com





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]