https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61578
--- Comment #29 from Dominik Vogt <vogt at linux dot vnet.ibm.com> --- I think I understand what's going on: Consider the patched code in match_reloads(): + = (ins[1] < 0 && REG_P (in_rtx) + && (int) REGNO (in_rtx) < lra_new_regno_start + && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx)) + ? lra_create_new_reg (inmode, in_rtx, goal_class, "") + : lra_create_new_reg_with_unique_value (outmode, out_rtx, + goal_class, "")); (1) This code normally makes a unique copy of the register in in_rtx, but if the register is marked as REG_DEAD in the curr_insn, it just makes a copy of the register using lra_create_new_reg(), with the same .val and .offset in the reg_info structure. (2) Further down in match_reloads, new insns are generated and stored in *before and *after. However, the new "after" insn still references the old register. In other words, in step (1) the code has made the assumption that the old register is no longer used, then generates an insn that uses it after it was marked as REG_DEAD. (3) Based on the bogus decision in (1), the condition in lra-lives.c decides that the two registers are identical copies and can be mapped to the same hard register: + && (((src_regno >= FIRST_PSEUDO_REGISTER + && (! sparseset_bit_p (pseudos_live, src_regno) + || (dst_regno >= FIRST_PSEUDO_REGISTER + && lra_reg_val_equal_p (src_regno, + lra_reg_info[dst_regno].val, + lra_reg_info[dst_regno].offset))