http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58220
Bug ID: 58220 Summary: [4.9 Regression] Many new failures for SH after rev. 201833 Product: gcc Version: 4.9.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: kkojima at gcc dot gnu.org Target: sh*-*-* There are many new execution errors on SH after the revision 201833 r201883 | tejohnson | 2013-08-20 22:29:53 +0900 (Tue, 20 Aug 2013) | 8 lines The change of final.c:reemit_insn_block_notes for r201883 ... - for (; insn; insn = next_active_insn (insn)) + for (; insn; insn = next_insn (insn)) { tree this_block; + /* Prevent lexical blocks from straddling section boundaries. */ + if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS) + { + for (tree s = cur_block; s != DECL_INITIAL (cfun->decl); + s = BLOCK_SUPERCONTEXT (s)) + { + rtx note = emit_note_before (NOTE_INSN_BLOCK_END, insn); + NOTE_BLOCK (note) = s; + note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn); + NOTE_BLOCK (note) = s; + } + } + + if (!active_insn_p (insn)) + continue; uses next_insn and active_insn_p pair instead of next_acrive_insn, though next_insn handles SEQUENCEs specially: rtx next_insn (rtx insn) { if (insn) { insn = NEXT_INSN (insn); if (insn && NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) insn = XVECEXP (PATTERN (insn), 0, 0); } return insn; } but next_active_insn does nothing special for SEQUENCEs: rtx next_active_insn (rtx insn) { while (insn) { insn = NEXT_INSN (insn); if (insn == 0 || active_insn_p (insn)) break; } return insn; } It looks now the for loop in reemit_insn_block_notes sees the inside insn of SEQUENCE, not SEQUENCE insn itself. The failures went away with the following one liner. * final.c (reemit_insn_block_notes): Use NEXT_INSN instead of next_insn. --- ORIG/trunk/gcc/final.c 2013-08-22 09:43:35.000000000 +0900 +++ trunk/gcc/final.c 2013-08-22 14:36:51.000000000 +0900 @@ -1650,7 +1650,7 @@ reemit_insn_block_notes (void) rtx insn, note; insn = get_insns (); - for (; insn; insn = next_insn (insn)) + for (; insn; insn = NEXT_INSN (insn)) { tree this_block; Here is the diff of the generated codes with/without the above patch for a typical example of failure gcc.c-torture/execute/20000422-1.c with -Og -g: --- good.s 2013-08-23 07:47:43.000000000 +0900 +++ bad.s 2013-08-23 07:47:16.000000000 +0900 @@ -27,6 +27,7 @@ main: .LBE2: .loc 1 17 0 bra .L2 + nop mov #0,r4 .LVL1: .align 1 where SH uses a SEQUENCE for bra instruction and its delayed slot which should be filled with nop in this case.