This patch fixes a stupid oversight in: 2008-10-24 Richard Sandiford <rdsandif...@googlemail.com>
* config/mips/mips.c (mips_canonicalize_move_class): New function. (mips_move_to_gpr_cost): Likewise. (mips_move_from_gpr_cost): Likewise. (mips_register_move_cost): Make more fine-grained. The idea was to handle the various subclasses and union classes correctly, but I missed out the case for M16_REGS. This meant that some MIPS16 moves were wrongly getting a cost of 0 instead of the correct cost of 2. That in turn caused a segfault when dividing by a register cost in gcc.dg/pr37156.c. I tried to see what effect this patch had on code size for -Os -mips16, but as usual it was a case of some better, some worse. The overall change was of the order of 0.01%. As a point of comparison I tried disabling Steve's patch to fix the $t registers and as expected the results were more consistently worse. Anyway, it's wrong to return 0 as a move cost for non-union classes, so we need something like this whatever happens. It probably doesn't make much sense to tune the costs further with reload instead of LRA. Tested on mips64-linux-gnu and applied. Thanks, Richard gcc/ * config/mips/mips.c (mips_move_to_gpr_cost): Add M16_REGS case. (mips_move_from_gpr_cost): Likewise. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2014-01-21 20:38:01.864324981 +0000 +++ gcc/config/mips/mips.c 2014-01-21 20:38:53.734788910 +0000 @@ -11883,6 +11883,7 @@ mips_move_to_gpr_cost (enum machine_mode { switch (from) { + case M16_REGS: case GENERAL_REGS: /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */ return 2; @@ -11919,6 +11920,7 @@ mips_move_from_gpr_cost (enum machine_mo { switch (to) { + case M16_REGS: case GENERAL_REGS: /* A MIPS16 MOVE instruction, or a non-MIPS16 MOVE macro. */ return 2;