http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56451
--- Comment #1 from Kazumoto Kojima <kkojima at gcc dot gnu.org> 2013-02-26 00:32:07 UTC --- Before dbr_schedule, the insns look like: r1 := 0xc0000000 (A) if (r5 > r1) goto L0 (B) if (r5 < r1) goto L1 r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: r0 := 2 L2: On SH, insns (A),(B),(C) can have delayed slot. dbr_schedule fills a slot of (A) first: r1 := 0xc0000000 (A) [if (r5 > r1) goto L2 | r0 := 2] (B) if (r5 < r1) goto L1 r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: r0 := 2 L2: Curiously, in the problematic case, dbr_schedule tries (C) next and redundant_insn checks that r0 := 2 is whether redundant or not with scanning insns backward from (C). It finds the insn in the slot of (A) and deletes the insn r0 := 2 at L0 as an unnecessary one. r1 := 0xc0000000 (A) [if (r5 > r1) goto L2 | r0 := 2] (B) if (r5 < r1) goto L1 r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: L2: Then dbr_schedule fills the slot of (B): r1 := 0xc0000000 (A) [if (r5 > r1) goto L2 | r0 := 2] (B) [if (r5 < r1) goto L2 | r0 := 1] r1 := 0x80000000 (C) if (r4 >= r1) goto L0 L1: r0 := 1 goto L2 L0: L2: Now (C) and r0 := 1 at L1 are useless because r0 is 1 before (C). It seems to me that the above is an unexpected scenario to redundant_insn, i.e. dbr_schedule uses it unsafely somewhere, though I gave up to find where problematic use occurs. An easy patch below might be a bit overkill but it fixes the problem for me. --- ORIG/trunk/gcc/reorg.c 2013-01-11 11:35:58.000000000 +0900 +++ trunk/gcc/reorg.c 2013-02-25 17:17:34.000000000 +0900 @@ -1514,7 +1514,7 @@ redundant_insn (rtx insn, rtx target, rt trial && insns_to_search > 0; trial = PREV_INSN (trial)) { - if (LABEL_P (trial)) + if (LABEL_P (trial) || JUMP_P (trial)) return 0; if (!INSN_P (trial))