This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/88033] [9 Regression] ICE on valid code at -O2 and -O3 on x86-64-linux-gnu: in remove_some_program_points_and_update_live_ranges, at lra-lives.c:1179
- From: "bergner at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 16 Nov 2018 18:51:39 +0000
- Subject: [Bug rtl-optimization/88033] [9 Regression] ICE on valid code at -O2 and -O3 on x86-64-linux-gnu: in remove_some_program_points_and_update_live_ranges, at lra-lives.c:1179
- Auto-submitted: auto-generated
- References: <bug-88033-4@http.gcc.gnu.org/bugzilla/>
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;