The following patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70461
I tried to do minimal changes. It is hard to create a test for the PR as the generated code can be changed in future. So the patch has no test.
The patch was bootstrapped and tested on x86-64. Committed as rev. 234649.
Index: ChangeLog =================================================================== --- ChangeLog (revision 234648) +++ ChangeLog (working copy) @@ -1,3 +1,9 @@ +2016-03-31 Vladimir Makarov <vmaka...@redhat.com> + + PR rtl-optimization/70461 + * ira-color.c (allocno_copy_cost_saving): Use allocno class if it + is necessary. + 2016-03-31 Martin Liska <mli...@suse.cz> PR hsa/70399 Index: ira-color.c =================================================================== --- ira-color.c (revision 234648) +++ ira-color.c (working copy) @@ -2734,10 +2734,16 @@ static int allocno_copy_cost_saving (ira_allocno_t allocno, int hard_regno) { int cost = 0; + enum machine_mode allocno_mode = ALLOCNO_MODE (allocno); enum reg_class rclass; ira_copy_t cp, next_cp; rclass = REGNO_REG_CLASS (hard_regno); + if (ira_reg_class_max_nregs[rclass][allocno_mode] + > ira_class_hard_regs_num[rclass]) + /* For the above condition the cost can be wrong. Use the allocno + class in this case. */ + rclass = ALLOCNO_CLASS (allocno); for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp) { if (cp->first == allocno) @@ -2754,7 +2760,7 @@ allocno_copy_cost_saving (ira_allocno_t } else gcc_unreachable (); - cost += cp->freq * ira_register_move_cost[ALLOCNO_MODE (allocno)][rclass][rclass]; + cost += cp->freq * ira_register_move_cost[allocno_mode][rclass][rclass]; } return cost; }