re PR target/9365 ([SH] segfault in gen_far_branch (config/sh/sh.c))
authorJ"orn Rennecke <joern.rennecke@superh.com>
Wed, 14 Jan 2004 18:02:42 +0000 (18:02 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Wed, 14 Jan 2004 18:02:42 +0000 (18:02 +0000)
        PR target/9365
        * sh.c (gen_block_redirect): Add special handling of RETURN.
        (gen_far_branch) Don't call gen_stuff_delay_slot if there is no
        far branch target (i.e. it's a return).

From-SVN: r75872

gcc/ChangeLog
gcc/config/sh/sh.c

index 7e0a7b9279d2f8df481912f0756da6c7d3770c0c..3ab2f54c2e99bdc28af605c92d2a36355d64a7fb 100644 (file)
@@ -1,3 +1,10 @@
+2004-01-14  J"orn Rennecke <joern.rennecke@superh.com>
+
+       PR target/9365
+       * sh.c (gen_block_redirect): Add special handling of RETURN.
+       (gen_far_branch) Don't call gen_stuff_delay_slot if there is no
+       far branch target (i.e. it's a return).
+
 2004-01-14  Kazu Hirata  <kazu@cs.umass.edu>
 
        * regrename.c (find_oldest_value_reg): Fix a warning.
index 8159c5aaaf71413865d443b54c02455489e889a2..43657e41e858de46c50fab355b15925256306008 100644 (file)
@@ -3368,6 +3368,14 @@ gen_block_redirect (rtx jump, int addr, int need_block)
       else if (recog_memoized (prev) == CODE_FOR_block_branch_redirect)
        need_block = 0;
     }
+  if (GET_CODE (PATTERN (jump)) == RETURN)
+    {
+      if (! need_block)
+       return prev;
+      /* Reorg even does nasty things with return insns that cause branches
+        to go out of range - see find_end_label and callers.  */
+      return emit_insn_before (gen_block_branch_redirect (GEN_INT (0)) , jump);
+    }
   /* We can't use JUMP_LABEL here because it might be undefined
      when not optimizing.  */
   dest = XEXP (SET_SRC (PATTERN (jump)), 0);
@@ -3535,11 +3543,16 @@ gen_far_branch (struct far_branch *bp)
   JUMP_LABEL (jump) = bp->far_label;
   if (! invert_jump (insn, label, 1))
     abort ();
-  (emit_insn_after
-   (gen_stuff_delay_slot
-    (GEN_INT (INSN_UID (XEXP (SET_SRC (PATTERN (jump)), 0))),
-     GEN_INT (recog_memoized (insn) == CODE_FOR_branch_false)),
-    insn));
+  /* If we are branching around a jump (rather than a return), prevent
+     reorg from using an insn from the jump target as the delay slot insn -
+     when reorg did this, it pessimized code (we rather hide the delay slot)
+     and it could cause branches to go out of range.  */
+  if (bp->far_label)
+    (emit_insn_after
+     (gen_stuff_delay_slot
+      (GEN_INT (INSN_UID (XEXP (SET_SRC (PATTERN (jump)), 0))),
+       GEN_INT (recog_memoized (insn) == CODE_FOR_branch_false)),
+      insn));
   /* Prevent reorg from undoing our splits.  */
   gen_block_redirect (jump, bp->address += 2, 2);
 }