[gcc r11-7154] Fix miscompilation of Python on HP-PA/Linux

Eric Botcazou ebotcazou@gcc.gnu.org
Tue Feb 9 18:56:24 GMT 2021


https://gcc.gnu.org/g:20f28986a8d3cad3c848d1e7da48f4bea7637298

commit r11-7154-g20f28986a8d3cad3c848d1e7da48f4bea7637298
Author: Eric Botcazou <ebotcazou@adacore.com>
Date:   Tue Feb 9 19:49:18 2021 +0100

    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:
---
 gcc/reorg.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

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<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;
 	    }


More information about the Gcc-cvs mailing list