https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87507
Peter Bergner <bergner at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2018-10-04 CC| |law at gcc dot gnu.org, | |vmakarov at gcc dot gnu.org Component|target |rtl-optimization Ever confirmed|0 |1 --- Comment #5 from Peter Bergner <bergner at gcc dot gnu.org> --- The other problem is that we don't add in the cost of saving and restoring non-volatile registers in the prologue and epilogue if HONOR_REG_ALLOC_ORDER is set (it is for rs6000): if (!HONOR_REG_ALLOC_ORDER) { if ((saved_nregs = calculate_saved_nregs (hard_regno, mode)) != 0) /* We need to save/restore the hard register in epilogue/prologue. Therefore we increase the cost. */ { rclass = REGNO_REG_CLASS (hard_regno); add_cost = ((ira_memory_move_cost[mode][rclass][0] + ira_memory_move_cost[mode][rclass][1]) * saved_nregs / hard_regno_nregs (hard_regno, mode) - 1); cost += add_cost; full_cost += add_cost; } } The code in Comment 4 is what gives reg pair r7,r8 a cost of 1000 and since we don't charge non-volatiles for prologue/epilogue save restore, reg pair r30,r31 gets a cost of zero, so assign_hard_reg picks r30,r31 and we get the unnecessary non-volatile reg usage we're seeing. It seems to me that we should always incorporate the save/restore cost into non-volatiles. However, even if we enable the code above for targets that set HONOR_REG_ALLOC_ORDER, there is still a bug in that the additional cost it computes above, because it doesn't take into consideration the basic block frequency assigned to the prologue and epilogue blocks. The additional cost above really should be multiplied by the prologue/epilogue frequency. The above analysis means this is no longer target bug, but a bug in the cost computation in IRA, therefore I am resetting the Component and adding Vlad and Jeff to the CC for their awareness. I have a patch to fix the above that I am testing.