Thread View: gnu.gcc.bug
1 messages
1 total messages
Started by Brendan Lynch - Sun Boston Devel...
Tue, 07 Apr 1992 17:32
Bug in gcc-2.1 (and 2.0): 'const' function calls.
Author: 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
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads