https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116600
--- Comment #9 from chenglulu <chenglulu at loongson dot cn> --- I found that there are two edges, 6->13 and 12->13, as shown in https://gcc.gnu.org/bugzilla/attachment.cgi?id=61211. When shrink-wrap optimizes 6->13, it finds that bb12 fall-through bb13. So it needs to split 12->13 first. There is an error in the split process. I tried to modify this part of the code and it solved the problem, but I'm not sure if the logic is correct. ``` diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc index d206c0d53a7..57bb4699c6a 100644 --- a/gcc/cfgrtl.cc +++ b/gcc/cfgrtl.cc @@ -1593,6 +1593,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) } } + bool adjust_jump_target = false; /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs don't point to the target or fallthru label. */ if (JUMP_P (BB_END (e->src)) @@ -1601,7 +1602,6 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) && (note = extract_asm_operands (PATTERN (BB_END (e->src))))) { int i, n = ASM_OPERANDS_LABEL_LENGTH (note); - bool adjust_jump_target = false; for (i = 0; i < n; ++i) { @@ -1615,33 +1615,6 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target)) asm_goto_edge = true; } - if (adjust_jump_target) - { - rtx_insn *insn = BB_END (e->src); - rtx note; - rtx_insn *old_label = BB_HEAD (e->dest); - rtx_insn *new_label = BB_HEAD (target); - - if (JUMP_LABEL (insn) == old_label) - { - JUMP_LABEL (insn) = new_label; - note = find_reg_note (insn, REG_LABEL_TARGET, new_label); - if (note) - remove_note (insn, note); - } - else - { - note = find_reg_note (insn, REG_LABEL_TARGET, old_label); - if (note) - remove_note (insn, note); - if (JUMP_LABEL (insn) != new_label - && !find_reg_note (insn, REG_LABEL_TARGET, new_label)) - add_reg_note (insn, REG_LABEL_TARGET, new_label); - } - while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label)) - != NULL_RTX) - XEXP (note, 0) = new_label; - } } if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge) @@ -1692,6 +1665,42 @@ force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label) } new_bb = jump_block; + + if (adjust_jump_target) + { + rtx_insn *insn = BB_END (new_edge->src); + rtx note; + rtx_insn *old_label = BB_HEAD (e->dest); + rtx_insn *new_label = BB_HEAD (jump_block); + + if (JUMP_LABEL (insn) == old_label) + { + rtx tmp = extract_asm_operands (PATTERN (insn)); + rtx_code_label *new_label = block_label (new_edge->dest); + rtx old_ref = ASM_OPERANDS_LABEL (tmp, 0); + gcc_assert (GET_CODE(old_ref) == LABEL_REF); + ASM_OPERANDS_LABEL (tmp, 0) = gen_rtx_LABEL_REF (Pmode, new_label); + JUMP_LABEL (insn) = new_label; + --LABEL_NUSES (old_label); + ++LABEL_NUSES (new_label); + note = find_reg_note (insn, REG_LABEL_TARGET, old_label); + if (note) + remove_note (insn, note); + + } + else + { + note = find_reg_note (insn, REG_LABEL_TARGET, old_label); + if (note) + remove_note (insn, note); + if (JUMP_LABEL (insn) != new_label + && !find_reg_note (insn, REG_LABEL_TARGET, new_label)) + add_reg_note (insn, REG_LABEL_TARGET, new_label); + } + while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label)) + != NULL_RTX) + XEXP (note, 0) = new_label; + } } else jump_block = e->src; ```