https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88033
--- Comment #3 from Peter Bergner <bergner at gcc dot gnu.org> --- So this is a problem when we have a simple copy from a reg to itself, like so: (insn (set (reg:DI XXX) (reg:DI XXX))) By definition, a register does not conflict with itself, but a copy of this type is confusing the code that is handling non conflicting copies and we're adding extra program points when we shouldn't. Since a register cannot conflict with itself, it's easier to just bail on these types of copies in non_conflicting_reg_copy_p() rather than trying to fix up the code to handle them. I'm regtesting the following patch that fixes the ICE for me. Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c (revision 266207) +++ gcc/ira-lives.c (working copy) @@ -1083,11 +1083,17 @@ non_conflicting_reg_copy_p (rtx_insn *insn) int src_regno = REGNO (SET_SRC (set)); machine_mode mode = GET_MODE (SET_DEST (set)); + /* By definition, a register does not conflict with itself, therefore we + do not have to handle it specially. Returning NULL_RTX now, helps + simplify the callers of this function. */ + if (dst_regno == src_regno) + return NULL_RTX; + /* Computing conflicts for register pairs is difficult to get right, so for now, disallow it. */ - if ((dst_regno < FIRST_PSEUDO_REGISTER + if ((HARD_REGISTER_NUM_P (dst_regno) && hard_regno_nregs (dst_regno, mode) != 1) - || (src_regno < FIRST_PSEUDO_REGISTER + || (HARD_REGISTER_NUM_P (src_regno) && hard_regno_nregs (src_regno, mode) != 1)) return NULL_RTX;