As noted in PR93996, haifa-sched can try to add REG_NOTEs to a NOTE_INSN. This causes memory corruption which typically shows up as a fault in the GC system.
What happens is we have an insn before the EPILOGUE_BEG note. That insn needs to be split and the split form creates new basic blocks. As a result we have a NOTE_INSN_BASIC_BLOCK right after the NOTE_EPILOGUE_BEG while the code in haifa-sched.c assume the next insn after the NOTE_EPILOGUE_BEG would be a real insn. The primary patch is Andrews. All I did was bullet proof it a bit by ensuring that we don't go past next_tail and asserting that after skippiong the NOTE_INSN_BASIC_BLOCK that we've got an INSN. Bootstrapped and regression tested on x86 and a variety of other platforms overnight in the tester. Committing to the trunk. Jeff
commit e6ce69cae5059dfd715edd4e26653c23baf4cb0f Author: Andrew Pinski <apin...@marvell.com> Date: Fri Mar 6 08:34:01 2020 -0700 Avoid putting a REG_NOTE on anything other than an INSN in haifa-sched.c PR rtl-optimization/93996 * haifa-sched.c (remove_notes): Be more careful when adding REG_SAVE_NOTE. diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 843648314ae..e38af8ed620 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-03-06 Andrew Pinski <apin...@marvell.com> + Jeff Law <l...@redhat.com> + + PR rtl-optimization/93996 + * haifa-sched.c (remove_notes): Be more careful when adding + REG_SAVE_NOTE. + 2020-03-06 Delia Burduv <delia.bur...@arm.com> * config/arm/arm_neon.h (vld2_bf16): New. diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 1d3de7b6a76..80687fb5359 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -4239,6 +4239,15 @@ remove_notes (rtx_insn *head, rtx_insn *tail) if (insn != tail) { remove_insn (insn); + /* If an insn was split just before the EPILOGUE_BEG note and + that split created new basic blocks, we could have a + BASIC_BLOCK note here. Safely advance over it in that case + and assert that we land on a real insn. */ + if (NOTE_P (next) + && NOTE_KIND (next) == NOTE_INSN_BASIC_BLOCK + && next != next_tail) + next = NEXT_INSN (next); + gcc_assert (INSN_P (next)); add_reg_note (next, REG_SAVE_NOTE, GEN_INT (NOTE_INSN_EPILOGUE_BEG)); break;