Richard Sandiford <rdsandif...@googlemail.com> writes: > In this case it's a MIPS backend bug. The single pressure class > for MIPS is ALL_REGS, and CLASS_MAX_NREGS (ALL_REGS, TImode) > is returning 4, based on the fact that ALL_REGS includes the > floating-point condition codes. (CCmode is hard-wired to 4 bytes, > so for CCV2 and CCV4, the correct number of registers is the size > of the mode divided by 4.) Since floating-point condition codes > can't store TImode, the backend should be ignoring them and > returning 2 instead. I'm testing a fix for that now.
Here's what I applied after testing mips64-linux-gnu. As well as fixing the wrong value for valid combinations, it has the side-effect of returning an over-the-top value for more invalid combinations than before. That's semi- intentional though. I don't think this macro is required to detect invalid modes, or return a specific value for them. Richard gcc/ * config/mips/mips.c (mips_class_max_nregs): Check that the mode is OK for ST_REGS and FP_REGS before taking those classes into account. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2011-08-20 19:44:44.000000000 +0100 +++ gcc/config/mips/mips.c 2011-08-20 19:49:06.000000000 +0100 @@ -10630,12 +10630,14 @@ mips_class_max_nregs (enum reg_class rcl COPY_HARD_REG_SET (left, reg_class_contents[(int) rclass]); if (hard_reg_set_intersect_p (left, reg_class_contents[(int) ST_REGS])) { - size = MIN (size, 4); + if (HARD_REGNO_MODE_OK (ST_REG_FIRST, mode)) + size = MIN (size, 4); AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) ST_REGS]); } if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS])) { - size = MIN (size, UNITS_PER_FPREG); + if (HARD_REGNO_MODE_OK (FP_REG_FIRST, mode)) + size = MIN (size, UNITS_PER_FPREG); AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) FP_REGS]); } if (!hard_reg_set_empty_p (left))