[Bug target/60604] [4.9 Regression] GCC incorrectly compiles s_csinh function on MIPS32 (32bit fp)

rsandifo at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Mar 30 21:39:00 GMT 2014


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

rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2014-03-30
     Ever confirmed|0                           |1

--- Comment #8 from rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> ---
The subregs on pseudos seem fine.  I think the problem comes when
IRA substitutes $f12 into them.  I.e.:

(insn 26 8 27 2 (set (subreg:SI (reg:DF 199 [ D.3267 ]) 0)
        (and:SI (subreg:SI (reg/v:DF 205 [ x ]) 0)
            (const_int 2147483647 [0x7fffffff])))
/home/richards/Downloads/reduced.c:25 157 {*andsi3}
     (nil))
(insn 27 26 9 2 (set (subreg:SI (reg:DF 199 [ D.3267 ]) 4)
        (subreg:SI (reg/v:DF 205 [ x ]) 4))
/home/richards/Downloads/reduced.c:25 286 {*movsi_internal}
     (nil))

becomes:

(insn 26 8 27 2 (set (subreg:SI (reg:DF 199 [ D.3267 ]) 0)
        (and:SI (subreg:SI (reg:DF 44 $f12) 0)
            (const_int 2147483647 [0x7fffffff])))
/home/richards/Downloads/reduced.c:25 157 {*andsi3}
     (nil))
(insn 27 26 9 2 (set (subreg:SI (reg:DF 199 [ D.3267 ]) 4)
        (subreg:SI (reg:DF 44 $f12) 4)) /home/richards/Downloads/reduced.c:25
286 {*movsi_internal}
     (nil))

These operands would normally be invalid register_operands thanks to:

#ifdef CANNOT_CHANGE_MODE_CLASS
      if (REG_P (sub)
      && REGNO (sub) < FIRST_PSEUDO_REGISTER
      && REG_CANNOT_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
      && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
      && GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
      /* LRA can generate some invalid SUBREGS just for matched
         operand reload presentation.  LRA needs to treat them as
         valid.  */
      && ! LRA_SUBREG_P (op))
    return 0;
#endif

The problem is that general_operand and nonmemory_operand don't check
the same thing.

You could argue that reload should be able to cope correctly with the
"invalid" subregs, and maybe LRA would, but really we shouldn't create
insns that we know are going to need a reload.

The problem is, general_operand, nonmemory_operand and register_operand
all have slightly different ideas what a register operand is.  So although
the patch I'm about to attach seems to fix it, it might be too drastic
for this stage.



More information about the Gcc-bugs mailing list