https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64300
Kazumoto Kojima <kkojima at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kkojima at gcc dot gnu.org --- Comment #1 from Kazumoto Kojima <kkojima at gcc dot gnu.org> --- I get the same ICE on my local sh-lra branch after r218688. I've looked at what is going on the test case in c#0 with the cross s390 compiler. It seems that the change at r218688 + if (GET_MODE (*curr_id->operand_loc[nop]) != VOIDmode + && ! hard_reg_set_empty_p (this_alternative_set) + && ! HARD_REGNO_MODE_OK (ira_class_hard_regs + [this_alternative][0], + GET_MODE (*curr_id->operand_loc[nop]))) doesn't work as intended for some targets. These lines are to check whether a requested mode value can be held by the registers in this_alternative class or not. In the problematic case, gdb shows that GET_MODE (*curr_id->operand_loc[nop]) is DImode and this_alternative is GENERAL_REGS. ira_class_hard_regs[this_alternative] is {1, 2, 3, 4, 5, 0, 11, 10, 9, 8, 7, 6, 0 <repeats 26 times>} which is a set of regno for GENERAL_REGS in the preferred allocation order. Then ira_class_hard_regs[this_alternative][0] is 1 and HARD_REGNO_MODE_OK (1, DImode) is false. I guess that s390 uses a register pair for DImode in this case and 1 is bad as the starting regno for DImode. Is it right? SH uses the similar allocation order of which the first regno isn't match to the register pair.