mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-06 02:20:34 +08:00
Fix miscompilation of Python on HP-PA/Linux
This is the miscompilation of Python at -O2 on HP-PA/Linux present on the mainline and 10 branch, caused by the presence of a call to __builtin_unreachable () in the middle of a heavily branchy code, which confuses the reorg pass. gcc/ PR rtl-optimization/96015 * reorg.c (skip_consecutive_labels): Minor comment tweaks. (relax_delay_slots): When deleting a jump to the next active instruction over a barrier, first delete the barrier if the jump is the only way to reach the target label.
This commit is contained in:
parent
a11ef53238
commit
20f28986a8
21
gcc/reorg.c
21
gcc/reorg.c
@ -139,9 +139,9 @@ skip_consecutive_labels (rtx label_or_return)
|
||||
/* __builtin_unreachable can create a CODE_LABEL followed by a BARRIER.
|
||||
|
||||
Since reaching the CODE_LABEL is undefined behavior, we can return
|
||||
any code label and we're OK at runtime.
|
||||
any code label and we're OK at run time.
|
||||
|
||||
However, if we return a CODE_LABEL which leads to a shrinked wrapped
|
||||
However, if we return a CODE_LABEL which leads to a shrink-wrapped
|
||||
epilogue, but the path does not have a prologue, then we will trip
|
||||
a sanity check in the dwarf2 cfi code which wants to verify that
|
||||
the CFIs are all the same on the traces leading to the epilogue.
|
||||
@ -3210,6 +3210,23 @@ relax_delay_slots (rtx_insn *first)
|
||||
&& ! condjump_in_parallel_p (jump_insn)
|
||||
&& ! (next && switch_text_sections_between_p (jump_insn, next)))
|
||||
{
|
||||
rtx_insn *direct_label = as_a<rtx_insn *> (JUMP_LABEL (insn));
|
||||
rtx_insn *prev = prev_nonnote_insn (direct_label);
|
||||
|
||||
/* If the insn jumps over a BARRIER and is the only way to reach
|
||||
its target, then we need to delete the BARRIER before the jump
|
||||
because, otherwise, the target may end up being considered as
|
||||
unreachable and thus also deleted. */
|
||||
if (BARRIER_P (prev) && LABEL_NUSES (direct_label) == 1)
|
||||
{
|
||||
delete_related_insns (prev);
|
||||
|
||||
/* We have just removed a BARRIER, which means that the block
|
||||
number of the next insns has effectively been changed (see
|
||||
find_basic_block in resource.c), so clear it. */
|
||||
clear_hashed_info_until_next_barrier (direct_label);
|
||||
}
|
||||
|
||||
delete_jump (jump_insn);
|
||||
continue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user