This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
GCC bug!
- To: egcs-bugs at egcs dot cygnus dot com
- Subject: GCC bug!
- From: Fabio Alemagna <falemagn at studenti dot unina dot it>
- Date: Mon, 14 Feb 2000 17:07:46 +0100
- Disposition-Notification-To: Fabio Alemagna <falemagn@studenti.unina.it>
Hi all.
I've dicovered a bug in gcc. It happens only in some circumstances: I've
discovered one of these, maybe there are others.
In attach you can see a limited, purified version of the program which
cause
the bug to happen.
To compile it just type "make". Eventually modify the header config.h to
match
your system. I know, the code is in some parts very ugly, but it's in a
very
early stage of completion, so do not take care of this.
My system configuration is:
a PC with Pentium II processor, Linux RedHat 6.1, egcs version 2.91.66
*NOT MODIFIED*, kernel version 2.2.12-20.
Working whit gdb and disassembled code I've noticed that the compiler
trash a
register in calling a function which have been declared have arguments
passed
in register.
*IMPORTANT*
* THIS HAPPEN ONLY, REPEAT *ONLY*, IF I COMPILE WITH -O2 FLAG: -O3, -O1
and
* -O0 works.
* Moreover this happens *only* if I declare function
* include/events.h/event_schedule(struct event *, ULONG) have parameter
passed
* in register instead of be inline or a normal function with parameters
on
* stack
the place where the bug happen is custom/custom.c at line 160:
copi1 = chipmem_bank.wget(cop_pc);
where cop_pc is the parameter trashed.
Below there are the disassembled versions of this piece of code, the
first is
compiled whith -O2 flag, which make the bug to happens, the 2nd is
compiled
whith -O3 flag:
-O2 version (BUG)
movl cop_pc,%ecx
movl %ecx,%eax #first use of eax and inutile intruction
(why
#not movl cop_pc,%eax ???
movl chipmem_bank+16,%eax #eax trashed!!!
call *%eax #this function get parameter in eax,
which
#here is used like a funtion pointer!!
movl %eax,%ecx #inutile instruction.... :/
movl %ecx,%ebx
-O3 version (SANE)
movl cop_pc,%ecx #(1)
movl chipmem_bank+16,%edx
movl %ecx,%eax #(2)
call *%edx
movl %eax,%edx #inutile instruction.... :/
movl %edx,%ebx
#(1) and (2) are a couple of inutile intructions, why not movl
cop_pc,%eax???
I think a cleaner, faster and bugless implementation is:
movl cop_pc,%eax
movl chipmem_bank+16,%edx
call *%edx
movl %eax,%ebx
I've worked around the bug by storing cop_pc in an auto variable (which
the
compiler allocate in a register).
Thanks for your interesting,
Fabio Alemagna
amiGate.bug.tgz
copper-bug.s.gz
copper-sane.s.gz