Related articles |
---|
re: Compiler bugs chase@world.std.com (David Chase) (2002-01-03) |
Re: Compiler bugs Peter-Lawrence.Montgomery@cwi.nl (2002-01-05) |
Re: Compiler bugs christian.bau@cbau.freeserve.co.uk (Christian Bau) (2002-01-05) |
Re: Compiler bugs chase@world.std.com (David Chase) (2002-01-14) |
compiler bugs SidTouati@inria.fr (Sid Touati) (2009-04-27) |
Re: compiler bugs DrDiettrich1@aol.com (Hans-Peter Diettrich) (2009-04-28) |
Re: compiler bugs r3jjs@yahoo.com (Jeremy J Starcher) (2009-04-28) |
Re: compiler bugs lkrupp@indra.com (Louis Krupp) (2009-04-28) |
[22 later articles] |
From: | Peter-Lawrence.Montgomery@cwi.nl (Peter L. Montgomery) |
Newsgroups: | comp.compilers |
Date: | 5 Jan 2002 01:31:31 -0500 |
Organization: | CWI, Amsterdam |
References: | 02-01-015 |
Keywords: | errors |
Posted-Date: | 05 Jan 2002 01:31:31 EST |
During the 1970's I worked at an US Army supercomputer site
with a Control Data (= CDC) 7600. Almost everyone used
the FTN compiler, which supported FORTRAN 66 with CDC extensions.
This compiler was optimizing 10 years before I saw UNIX compilers
doing likewise.
I assisted many users, and reported numerous compiler bugs.
Two strange ones resembled:
*) A compiler internal error (abort). I repeatedly eliminated
parts of the code until I got down to
SUBROUTINE ONE
COMMON/C/ YYY
LEVEL 2, YYY
NAMELIST/XXX/ YYY
END
NAMELIST was a common FORTRAN extension, grouping several variable
or array names for use in I/O statements.
The LEVEL 2 statement says that variable YYY (hence common block /C/)
resides in extended memory, also known as LCM.
The hardware had separate instructions
for accessing operands in regular and extended memory.
Identifying a small program which aborts is not unusual.
What seemed strange is that the problem disappeared
when I renamed YYY. It seemed the offending variable name needed
to be exactly three characters and reside in LCM.
*) An anomaly of ones' complement arithmetic.
SUBROUTINE TWO(X, Y)
REAL X(100), Y(100)
LEVEL 2, Y
DO 10 I = 1, 100
X(I) = Y(I)
10 CONTINUE
END
The generated code for the loop resembled (N.B. FORTRAN 66
subscripts start at 1, addresses are in words rather than bytes):
SA1 A0 X1 = address of first argument (X)
SA2 A0+1 X2 = address of second argument (Y)
IX0 X2-X1 X0 = address(Y) - address(X)
SB7 X1 B7 = address(X(I)) = address(X(1))
SB6 X1+99 B6 = address(X(100))
LOOP
SX4 X0+B7 X4 = (Y - X) + address(X(I)) = address(Y(I))
RX7 X4 Read Y(I) from LCM to X7
SA7 B7 Store Y(I) in X(I)
SB7 B7+1 Advance address(X(I))
GE B6,B7 End of loop test
What's wrong? The IX0 X2-X1 computation is done in 60-bit
ones' complement arithmetic, while SX4 X0+B7 is done in
18-bit ones' complement arithmetic, ignoring the upper 42 bits of X0,
The other contributing factor is that the compiler sets the sign bit
when passing an LCM address to a subroutine
(the RX7 X4 ignores the upper bits of the address in X4).
If the address of Y is numerical smaller than that of X, such as
address(Y) = 40000000000000001000B,
address(X) = 00000000000000002000B (B = octal)
then X0 = 37777777777777777000B starts with 3777
(borrowing from the sign bit).
On the first iteration, X0+B7 = 777000B + 002000B
evaluates as 001001B due to an end-around carry. Whoops!
--
Peter-Lawrence.Montgomery@cwi.nl Home: San Rafael, California
Microsoft Research and CWI
Return to the
comp.compilers page.
Search the
comp.compilers archives again.