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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Target|mips*-*-*                   |mips*-*-* (o32/eabi32)
            Summary|GCC incorrectly compiles    |GCC incorrectly compiles
                   |s_csinh function on MIPS    |s_csinh function on MIPS32
                   |                            |(32bit fp)

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
The code generation looks incorrect to me:

    mfc1    $3,$f12
    mfc1    $2,$f12
    move    $17,$3
    jal    myclassify
    ext    $16,$2,0,31


Notice how $2/$3 are moving from the same register, one of them should have
been $f13.


The problem is due to paired floating point registers are swapped for
big-endian.
/* Paired FPRs are always ordered little-endian.  */

So when the register allocator is figuring out which register to copy from for
the high subreg of the DF mode:
(insn 23 22 24 (set (subreg:SI (reg:DF 200 [ D.2940 ]) 0)
        (and:SI (subreg:SI (reg:DF 194 [ D.2940 ]) 0)
            (const_int 2147483647 [0x7fffffff]))) t77.c:25 -1
     (nil))

It decides that is the same as the register which is incorrect for pair float.

This is what the register allocator produces:

(insn 110 8 23 2 (set (reg:SI 2 $2)
        (reg:SI 44 $f12)) t77.c:25 302 {*movsi_internal}
     (nil))
(insn 23 110 111 2 (set (reg:SI 16 $16 [ D.2940 ])
        (and:SI (reg:SI 2 $2)
            (const_int 2147483647 [0x7fffffff]))) t77.c:25 157 {*andsi3}
     (nil))

This is incorrect as we should be using $f13 or the full DI mode instead.

Reply via email to