[Bug c/12754] New: Faulty register allocation under certain circumstances

heiko dot panther at web dot de gcc-bugzilla@gcc.gnu.org
Fri Oct 24 09:34:00 GMT 2003


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12754

           Summary: Faulty register allocation under certain circumstances
           Product: gcc
           Version: 3.2.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: heiko dot panther at web dot de
                CC: gcc-bugs at gcc dot gnu dot org,wilson at specifixinc
                    dot com
 GCC build triplet: powerpc-apple-darwin
  GCC host triplet: powerpc-apple-darwin
GCC target triplet: or32-none-elf

This bug is not specific to the host or target it was met on. It is merely connected to the size of the 
type HARD_REG_SET on the host and the number of hard registers of the target. Bug appeared in 
gcc-3.1 as well.

I already talked about this to Jim Wilson, who seemed willing to work on it, so I CC'd him :)

Here's the full report:

I'm porting a gcc-3.2.3 cross compiler for or32 to a Mac OS X host.
The or32 is a 32 bit machine with 32 registers (r0..r31). The gcc
compiler I'm porting works fine for i86-linux. It is available from cvs@cvs.opencores.org:/home/
oc/cvs or1k/gcc-3.2.3

In find_reg(), global.c:1056 ff, something bad happens. find_reg is
processing a request for a DI (double integer, needs two registers), and
it finds r31 suitable. I assume it is not suitable, since there is no
r32 to hold the second part of the DI.

TEST_HARD_REG_BIT(used, 32) returns 0 and thus r32 is believed to be
available. This happens because "used" is  of type HARD_REG_SET.
HARD_REG_SET is a 32 bit integer type, so a test for nonexisting bits
will produce wrong results.

It seems perfectly legal for HARD_REG_SET to be 32 bits wide. In
hard-reg-set.h, HARD_REG_SET is #defined a HARD_REG_ELT_TYPE given that
HARD_REG_ELT_TYPE has at least as many bits as the target has got registers.

If I am not mistaken, this would generally mean that find_reg() might
yield errors for n-bit targets if the host HARD_REG_SET is not more than
n bits wide. The reason that the x86 port works could be that the
HARD_REG_SET is 64 bit wide there for some reason, but I did not check
that.

It could be argued that HARD_REG_ELT_TYPE is a native wide type, and
should therefore be 64 bits wide on PPC. I didn't look into why it isn't
in my gcc, but as stated above, it should be legal to have a 32 bit type
there.

A grep for TEST_HARD_REG_BIT yields about 220 occurences, about 100 in gcc, the rest in target 
configs (mainly IA32/64). All these places would have to be checked.



More information about the Gcc-bugs mailing list