The late-combine patch has triggered a previously latent bug in reorg.
Basically we have a sequence like this in the middle of reorg before we
start relaxing delay slots (cris-elf, gcc.dg/torture/pr98289.c)
(insn 67 49 18 (sequence [
(jump_insn 50 49 52 (set (pc)
(if_then_else (ne (reg:CC 19 ccr)
(const_int 0 [0]))
(label_ref:SI 30)
(pc))) "j.c":10:6 discrim 1 282 {*bnecc}
(expr_list:REG_DEAD (reg:CC 19 ccr)
(int_list:REG_BR_PROB 7 (nil)))
-> 30)
(insn/f 52 50 18 (set (mem:SI (reg/f:SI 14 sp) [1 S4 A8])
(reg:SI 16 srp)) 37 {*mov_tomemsi}
(nil))
]) "j.c":10:6 discrim 1 -1
(nil))
(note 18 67 54 [bb 3] NOTE_INSN_BASIC_BLOCK)
(note 54 18 55 NOTE_INSN_EPILOGUE_BEG)
(jump_insn 55 54 56 (return) "j.c":14:1 228 {*return_expanded}
(nil)
-> return)
(barrier 56 55 43)
(note 43 56 65 [bb 4] NOTE_INSN_BASIC_BLOCK)
(note 65 43 30 NOTE_INSN_SWITCH_TEXT_SECTIONS)
(code_label 30 65 8 5 6 (nil) [1 uses])
(note 8 30 61 [bb 5] NOTE_INSN_BASIC_BLOCK)
So at a high level the things to note are that insn 50 conditionally
jumps around insn 55. Second there's a SWITCH_TEXT_SECTIONS note
between insn 50 and the target label for insn 50 (code_label 30).
reorg sees the conditional jump around the unconditional jump/return and
will invert the jump and retarget the original jump to an appropriate
location. In this case generating:
(insn 67 49 18 (sequence [
(jump_insn 50 49 52 (set (pc)
(if_then_else (eq (reg:CC 19 ccr)
(const_int 0 [0]))
(label_ref:SI 68)
(pc))) "j.c":10:6 discrim 1 281 {*beqcc}
(expr_list:REG_DEAD (reg:CC 19 ccr)
(int_list:REG_BR_PROB 1073741831 (nil)))
-> 68)
(insn/s/f 52 50 18 (set (mem:SI (reg/f:SI 14 sp) [1 S4 A8])
(reg:SI 16 srp)) 37 {*mov_tomemsi}
(nil))
]) "j.c":10:6 discrim 1 -1
(nil))
(note 18 67 54 [bb 3] NOTE_INSN_BASIC_BLOCK)
(note 54 18 43 NOTE_INSN_EPILOGUE_BEG)
(note 43 54 65 [bb 4] NOTE_INSN_BASIC_BLOCK)
(note 65 43 8 NOTE_INSN_SWITCH_TEXT_SECTIONS)
(note 8 65 61 [bb 5] NOTE_INSN_BASIC_BLOCK)
[ ... ]
Where the new target of the jump is a return statement later in the IL.
Note that we now have a SWITCH_TEXT_SECTIONS note that is not
immediately preceded by a BARRIER. That triggers an assertion in the
dwarf2 code. Removal of the BARRIER is inherent in this optimization.
The fix is simple, we avoid this optimization when there's a
SWITCH_TEXT_SECTIONS note between the conditional jump insn and its
target. Thankfully we already have a routine to test for this in reorg,
so we just need to call it appropriately. The other approach would be
to drop the note which I considered and discarded.
We don't have great coverage for delay slot targets. I've tested arc,
cris, fr30, frv, h8, iq2000, microblaze, or1k, sh3 visium in my tester
as crosses without new regressions, fixing one regression along the way.
Bootstrap & regression testing on sh4 and hppa will take considerably
longer.
Pushing to the trunk momentarily.
Jeff
gcc/
* reorg.cc (relax_delay_slots): Do not optimize a conditional
jump around an unconditional jump/return in the presence of
a text section switch.
diff --git a/gcc/reorg.cc b/gcc/reorg.cc
index 99228a22c69..633099ca765 100644
--- a/gcc/reorg.cc
+++ b/gcc/reorg.cc
@@ -3409,7 +3409,8 @@ relax_delay_slots (rtx_insn *first)
&& next && simplejump_or_return_p (next)
&& (next_active_insn (as_a<rtx_insn *> (target_label))
== next_active_insn (next))
- && no_labels_between_p (insn, next))
+ && no_labels_between_p (insn, next)
+ && !switch_text_sections_between_p (insn, next_active_insn (next)))
{
rtx label = JUMP_LABEL (next);
rtx old_label = JUMP_LABEL (delay_jump_insn);