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.