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.