[Bug target/91052] [10 Regression] ICE in fix_reg_equiv_init, at ira.c:2705
linkw at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Feb 3 14:45:00 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91052
Kewen Lin <linkw at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |amodra at gcc dot gnu.org
--- Comment #12 from Kewen Lin <linkw at gcc dot gnu.org> ---
The insn 59 is deleted and new insn 219 is generated by function
combine_and_move_insns, the failure is due to that:
Originally insn 59 has the note that the updated reg r121 is REG_UNUSED.
Later insn 219 inserted before r184's use, with note directly copied from
insn 59, r121 is still REG_UNUSED.
So function setup_reg_equiv doesn't filter it out since it's taken as
single_set due to REG_UNUSED existence.
But the r121 in insn 219 isn't actually REG_UNUSED and gets fixed after live
info recalculation as below:
67: NOTE_INSN_BASIC_BLOCK 8
...
103: NOTE_INSN_DELETED
77: {r191:SF=[sfp:SI-0x18c];r121:SI=sfp:SI-0x18c;}
REG_UNUSED r121:SI
60: r122:SI=r127:SI
REG_DEAD r127:SI
219: {r184:SF=[sfp:SI-0x190];r121:SI=sfp:SI-0x190;}
61: [r122:SI]=r184:SF
REG_DEAD r184:SF
79: [++r122:SI]=r191:SF
REG_DEAD r191:SF
REG_INC r122:SI
Then fix_reg_equiv_init find the insn isn't single_set and assertion fail.
The newly generated doesn't look incorrect since some semantic changes as
below.
* Before combine_and_move_insns, we have:
67: NOTE_INSN_BASIC_BLOCK 8
58: NOTE_INSN_DELETED
63: NOTE_INSN_DELETED
110: NOTE_INSN_DELETED
88: NOTE_INSN_DELETED
76: NOTE_INSN_DELETED
103: NOTE_INSN_DELETED
59: {r184:SF=[sfp:SI-0x190];r121:SI=sfp:SI-0x190;}
REG_UNUSED r121:SI
77: {r191:SF=[sfp:SI-0x18c];r121:SI=sfp:SI-0x18c;}
60: r122:SI=r127:SI
REG_DEAD r127:SI
61: [r122:SI]=r184:SF
REG_DEAD r184:SF
79: [++r122:SI]=r191:SF
REG_DEAD r191:SF
REG_INC r122:SI
64: r187:SF=[r137:SI+low(`*.LC0')]
99: r198:SF=[++r121:SI] =====> with sp-0x18c+4;
REG_INC r121:SI
104: r201:SF=[r137:SI+low(`*.LC0')]
65: [r126:SI]=r187:SF
REG_DEAD r187:SF
105: [r126:SI]=r201:SF
REG_DEAD r201:SF
101: [++r122:SI]=r198:SF
REG_DEAD r198:SF
REG_INC r122:SI
114: L114:
113: NOTE_INSN_BASIC_BLOCK 9
* After combine_and_move_insns, we have:
67: NOTE_INSN_BASIC_BLOCK 8
58: NOTE_INSN_DELETED
63: NOTE_INSN_DELETED
110: NOTE_INSN_DELETED
88: NOTE_INSN_DELETED
76: NOTE_INSN_DELETED
103: NOTE_INSN_DELETED
77: {r191:SF=[sfp:SI-0x18c];r121:SI=sfp:SI-0x18c;}
REG_UNUSED r121:SI
60: r122:SI=r127:SI
REG_DEAD r127:SI
219: {r184:SF=[sfp:SI-0x190];r121:SI=sfp:SI-0x190;}
61: [r122:SI]=r184:SF
REG_DEAD r184:SF
79: [++r122:SI]=r191:SF
REG_DEAD r191:SF
REG_INC r122:SI
64: r187:SF=[r137:SI+low(`*.LC0')]
REG_EQUIV [r137:SI+low(`*.LC0')]
99: r198:SF=[++r121:SI] =====> still with sp-0x18c;
REG_INC r121:SI
104: r201:SF=[r137:SI+low(`*.LC0')]
REG_EQUIV [r137:SI+low(`*.LC0')]
65: [r126:SI]=r187:SF
REG_DEAD r187:SF
105: [r126:SI]=r201:SF
REG_DEAD r201:SF
101: [++r122:SI]=r198:SF
REG_DEAD r198:SF
REG_INC r122:SI
114: L114:
113: NOTE_INSN_BASIC_BLOCK 9
As above, I guess we can guard the strict single_set condition for function
combine_and_move_insns.
@@ -3827,7 +3874,7 @@ combine_and_move_insns (void)
/* Move the initialization of the register to just before
USE_INSN. Update the flow information. */
- else if (prev_nondebug_insn (use_insn) != def_insn)
+ else if (prev_nondebug_insn (use_insn) != def_insn && !multiple_sets
(def_insn))
{
rtx_insn *new_insn;
Or any alternative to ensure multiple sets movement doesn't kill usused reg's
live range and notes gets updated.
-----
Hi @Alan/@Vladimir,
What do you think of the issue? Thanks!
More information about the Gcc-bugs
mailing list