Article View: gnu.gcc.bug
Article #225Bug in gcc-2.1 (and 2.0): 'const' function calls.
From: Brendan Lynch - Sun Boston Devel...
Date: Tue, 07 Apr 1992 17:32
Date: Tue, 07 Apr 1992 17:32
152 lines
3712 bytes
3712 bytes
The gcc-2.1 compiler does not correctly handle deferred argument
poping in a routine in which calls to 'const' functions have been
removed during optimization. This problem is not
architecture-specific, but should affect all machines for which
deferred argument popping is allowed.
The following example shows this:
The routine:
-------------------------
extern double const sqrt(double);
double a[8];
extern void func2();
void
init(void)
{
a[0] = sqrt(1.5);
a[1] = 2 * sqrt(3.25);
a[2] = 2 * sqrt(3.25);
a[3] = 2 * sqrt(3.65);
a[4] = 3 * sqrt(3.25);
func2(a);
}
-------------------------
generates the following code on a Sun386 (Sun syntax assembler):
-----------------------------
.file "trysc.c"
.version "GNU C 2.1"
.optim
gcc2_compiled.:
.text
.align 4
.LC0:
.double 3.0000000000000000000000e+00
.align 4
.globl init
init:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
pushl $1073217536
pushl $0
call sqrt
fstpl a
pushl $1074397184
pushl $0
call sqrt
fstpl -8(%ebp)
fldl -8(%ebp)
fadd %st(0),%st
fstl a+8
fstpl a+16
pushl $1074606899
pushl $858993459
call sqrt
fadd %st(0),%st
fstpl a+24
fldl -8(%ebp)
fmull .LC0
fstpl a+32
addl $40,%esp << error
pushl $a
call func2
leave
ret
.align 4
.comm a,64
-----------------------------
The erroneous staement is that which pushes 40 bytes from the stack.
Although there were originally 5 calls to 'sqrt' (each pushing 8 bytes
of arguments), 2 of them have been optimized away, leaving only 24
bytes of arguments on the stack. Popping 40 bytes causes the stack to
get messed up.
The expand_call routine, in "calls.c" at line 598, has code which
looks as if it were intended to avoid this problem:
/* When calling a const function, we must pop the stack args right away,
so that the pop is deleted or moved with the call. */
if (is_const)
NO_DEFER_POP;
Unfortunately this only sets the 'inhibit_defer_pop' flag which is
reset to the value of 'old_inhibit_defer_pop' in 'emit_call_1'
*before* the check to see if the caller must pop the arguments
immediatley after the call.
The fix I have implemented is to set 'old_inhibit_defer_pop' at the
same time; this seems to generate correct code, but I am not sure if
it is the best fix for this problem.
With this fix in place, the following code is generated:
-----------------------------------------
.file "trysc.c"
.version "GNU C 2.1"
.optim
gcc2_compiled.:
.text
.align 4
.LC0:
.double 3.0000000000000000000000e+00
.align 4
.globl init
init:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
pushl $1073217536
pushl $0
call sqrt
addl $8,%esp
fstpl a
pushl $1074397184
pushl $0
call sqrt
addl $8,%esp
fld %st(0)
fadd %st,%st(1)
fxch %st(1)
fstl a+8
fstpl a+16
pushl $1074606899
pushl $858993459
fstpl -8(%ebp)
call sqrt
addl $8,%esp
fadd %st(0),%st
fstpl a+24
fldl -8(%ebp)
fmull .LC0
fstpl a+32
pushl $a
call func2
leave
ret
.align 4
.comm a,64
--------------------------------
- ---------------------------------------------
Brendan Lynch
EMail: internal: blynch@East
external: Brendan.Lynch@East.Sun.COM
Technical Details
Message-ID:
<9204071732.AA06883@amandla.East.Sun.COM>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!east.SUn.COM!Brendan.LynchShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!east.SUn.COM!Brendan.Lynch From: Brendan.Lynch@east.SUn.COM (Brendan Lynch - Sun Boston Development Center Software) Subject: Bug in gcc-2.1 (and 2.0): 'const' function calls. Message-ID: <9204071732.AA06883@amandla.East.Sun.COM> Sender: gnulists@ai.mit.edu Organization: GNUs Not Usenet Distribution: gnu Date: Tue, 7 Apr 1992 17:32:50 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 154