https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91102
--- Comment #5 from Vladimir Makarov <vmakarov at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #1) > > Vlad, could you please have a look? The culprit patch is actually https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=265942 Prohibiting reload for any user defined registers which should be matched is too harsh. We still can reload operands using the match if no one is an earlier clobber operand. The following patch should solve the problem: Index: ../../gcc/gcc/lra-constraints.c =================================================================== --- ../../gcc/gcc/lra-constraints.c (revision 273177) +++ ../../gcc/gcc/lra-constraints.c (working copy) @@ -2172,8 +2172,9 @@ else { /* Operands don't match. If the operands are - different user defined explicit hard registers, - then we cannot make them match. */ + different user defined explicit hard + registers, then we cannot make them match + when one is early clobber operand. */ if ((REG_P (*curr_id->operand_loc[nop]) || SUBREG_P (*curr_id->operand_loc[nop])) && (REG_P (*curr_id->operand_loc[m]) @@ -2191,10 +2192,14 @@ && REG_USERVAR_P (nop_reg) && REG_P (m_reg) && HARD_REGISTER_P (m_reg) - && REG_USERVAR_P (m_reg)) - break; + && REG_USERVAR_P (m_reg)) { + for (int i = 0; i < early_clobbered_regs_num; i++) + if (m == early_clobbered_nops[i]) + break; + if (i < early_clobbered_regs_num || early_clobber_p) + break; + } } - /* Both operands must allow a reload register, otherwise we cannot make them match. */ if (curr_alt[m] == NO_REGS) Although I'll take some time to think about the solution before submitting it into the trunk.