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.