UltraSPARC 16-bit assignments severely broken [analysis]

Charles M. Hannum root@ihack.net
Sat Jul 22 20:24:00 GMT 2000


With gcc 2.95.2, configured for sparc64-elf, the following code does
not compile:

struct ppp_softc {
        short   sc_flags;                
} ppp_softc[2];
void
pppattach()
{
        struct ppp_softc *sc;
        int i;
        for (sc = ppp_softc, i = 0; i < 2; sc++)
                sc->sc_flags = 0x8010;
}

I get:

lop-nor$ sparc64-elf-gcc -O -Av9a foo.i
foo.i: In function `pppattach':
foo.i:11: Internal compiler error in `sparc_emit_set_const32', at ./config/sparc/sparc.c:1178
Please submit a full bug report.
See <URL: http://www.gnu.org/software/gcc/faq.html#bugreport > for instructions.
lop-nor$ 

The problem has to do with loop hoisting and movhi.  When the parser
generates the 16-bit assignment inside the loop,
sparc_emit_set_const32() splits it into a two-part load:

(insn 21 19 22 (set (reg:HI 110)
        (const_double (const_int 0 [0x0]) -32768 [0xffff8000] 0 [0x0] 0 [0x0] 0 [0x0] 0 [0x0])) -1 (nil)
    (nil))

(insn 22 21 23 (set (reg:HI 109)
        (ior:HI (reg:HI 110)
            (const_int 16 [0x10]))) -1 (nil)
    (expr_list:REG_EQUAL (const_int -32752 [0xffff8010])
        (nil)))

Loop optimization then tries to hoist the first movhi out of the loop.
The movhi pattern converts the double to an int immediately, and then
passes it back into sparc_emit_set_const32().  The problem is that
this value does not require a two-part load, and therefore
sparc_emit_set_const32() aborts.

There are several different ways to fix this.  It may be that the code
at the top of movhi:

  /* Working with CONST_INTs is easier, so convert
     a double if needed.  */
  if (GET_CODE (operands[1]) == CONST_DOUBLE)
    operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));

should be removed, and the code further down should merely check that
the operand is a valid CONST_DOUBLE load -- effectively passing the
operand through unchanged in the loop hoisting case.  In mot sure
whether this might cause problems in other cases, but I suspect not,
since nothing else should be generating a CONST_DOUBLE operaned to a
movhi.

Any comments?



More information about the Gcc-bugs mailing list