A serious -fpic and -fomit-frame-pointer bug in egcs 1.0.3/1.1
H.J. Lu
hjl@lucon.org
Wed Jun 17 23:28:00 GMT 1998
> > That is fine to put the PIC base register in ebx. But eliminate_regs ()
> > doesn't know anything about PIC and ebx. When eliminate_regs replaces
> > ebp with esp, it assumes the top of the stack is for the temporary
> > variable. But with PIC, the top of the stack is changed to ebx. When
> > the function epilogue pops ebx, some garbage is put into ebx. You
> > can see the asm output for yourself.
> I don't see how eliminate_regs plays into this at all.
eliminate_regs called by reload in egcs 1.0.3 around line 979
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (reg_renumber[i] < 0 && reg_equiv_memory_loc[i])
{
rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX, 0);
In my test case, reg_equiv_memory_loc[i] is 16(%ebp) and (%esp) is
returned since eliminate_regs knows 16(%ebp) == (%esp). But it is
in the global register allocation. It knows nothing about PIC and
ebx.
Now the fucntion prologue/epilogue do
exp__H1Zd_RCt7complex1ZX01_t7complex1ZX01:
subl $16,%esp
pushl %ebx
call .L22
.L22:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-.L22],%ebx
......
fstpl (%esp)
......
popl %ebx
addl $16,%esp
ret $4
Please tell me what happens to ebx. It is because the fucntion
prologue/epilogue do something behind the back of the compiler.
eliminate_regs doesn't know it. If we disable -fomit-frame-pointer
for PIC or change the prologue/epilogue to
exp__H1Zd_RCt7complex1ZX01_t7complex1ZX01:
pushl %ebx
call .L22
.L22:
popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-.L22],%ebx
subl $16,%esp
......
fstpl (%esp)
......
addl $16,%esp
popl %ebx
ret $4
the bug will disappear. BTW, can we change the prologue/epilogue
like that? Will it break gdb?
H.J.
More information about the Gcc-bugs
mailing list