From: Eric Botcazou Date: Tue, 9 Feb 2021 18:49:18 +0000 (+0100) Subject: Fix miscompilation of Python on HP-PA/Linux X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=20f28986a8d3cad3c848d1e7da48f4bea7637298;p=gcc.git 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. --- diff --git a/gcc/reorg.c b/gcc/reorg.c index fc184202778..69c9a768fa9 100644 --- a/gcc/reorg.c +++ b/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 (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; }