This patch is to fix 2 issues found in dbr_schedule when trying to fix PR target/64761. The first is relax_delay_slots removes the jump insn in the insns like below:
(jump_insn/j 74 58 59 (set (pc) (label_ref:SI 29)) ...) (barrier 59 74 105) (note 105 59 29 NOTE_INSN_SWITCH_TEXT_SECTIONS) (code_label 29 105 30 31 "" [5 uses]) (insn 31 30 32 (set (reg ... i.e. relax_delay_slot tries to delete the jump insn pointing to the next active insn of that jump insn as a trivial jump even when there is a NOTE_INSN_SWITCH_TEXT_SECTIONS note between that jump and its next active insn. The second issue is that relax_delay_slots does a variant of follow jump optimization without checking targetm.can_follow_jump. -- PR target/64761 * reorg.c (switch_text_sections_between_p): New function. (relax_delay_slots): Call it when testing if the jump insn is removable. Use targetm.can_follow_jump when testing if the conditional branch can follow an unconditional jump. diff --git a/reorg.c b/reorg.c index 326fa53..2387910 100644 --- a/reorg.c +++ b/reorg.c @@ -3211,6 +3211,19 @@ label_before_next_insn (rtx x, rtx scan_limit) return insn; } +/* Return TRUE if there is a NOTE_INSN_SWITCH_TEXT_SECTIONS note in between + BEG and END. */ + +static bool +switch_text_sections_between_p (const rtx_insn *beg, const rtx_insn *end) +{ + const rtx_insn *p; + for (p = beg; p != end; p = NEXT_INSN (p)) + if (NOTE_P (p) && NOTE_KIND (p) == NOTE_INSN_SWITCH_TEXT_SECTIONS) + return true; + return false; +} + /* Once we have tried two ways to fill a delay slot, make a pass over the code to try to improve the results and to do such things as more jump @@ -3247,7 +3260,8 @@ relax_delay_slots (rtx_insn *first) target_label = find_end_label (target_label); if (target_label && next_active_insn (target_label) == next - && ! condjump_in_parallel_p (insn)) + && ! condjump_in_parallel_p (insn) + && ! (next && switch_text_sections_between_p (insn, next))) { delete_jump (insn); continue; @@ -3262,12 +3276,13 @@ relax_delay_slots (rtx_insn *first) /* See if this jump conditionally branches around an unconditional jump. If so, invert this jump and point it to the target of the - second jump. */ + second jump. Check if it's possible on the target. */ if (next && simplejump_or_return_p (next) && any_condjump_p (insn) && target_label && next_active_insn (target_label) == next_active_insn (next) - && no_labels_between_p (insn, next)) + && no_labels_between_p (insn, next) + && targetm.can_follow_jump (insn, next)) { rtx label = JUMP_LABEL (next);