This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix delayed branch scheduling (PR rtl-optimization/23454)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, Eric Botcazou <ebotcazou at libertysurf dot fr>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 1 Sep 2005 14:54:41 -0400
- Subject: [PATCH] Fix delayed branch scheduling (PR rtl-optimization/23454)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
invert_jump requires a conditional jump (aka any_condjump_p) as argument and
aborts if it is not conditional jump. But big part of reorg still uses the
old deprecated condjump_p (insn) and condjump_in_parallel_p (insn)
functions, sometimes when it means conditional or unconditional jump,
sometimes when it only means conditional jump and not unconditional.
I think the latter is the case when invert_jump is called in
relax_delay_slots - the optimization simplifies conditional jump around
unconditional jump (unconditional jump around unconditional jump makes no
sense).
I have tested on a cross this fixes the PR testcase, but will not be able to
bootstrap this in the short term on any target using dbr (sparc*, mips*).
Eric (or anybody else), could you please give this a shot?
2005-09-01 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/23454
* reorg.c (relax_delay_slots): Only call invert_jump if any_condjump_p
is true.
* g++.dg/opt/pr23454.C: New test.
--- gcc/reorg.c.jj 2005-08-06 10:39:59.000000000 +0200
+++ gcc/reorg.c 2005-09-01 20:30:28.000000000 +0200
@@ -3123,10 +3123,11 @@ relax_delay_slots (rtx first)
if (target_label && target_label != JUMP_LABEL (insn))
reorg_redirect_jump (insn, target_label);
- /* See if this jump branches around an unconditional jump.
- If so, invert this jump and point it to the target of the
+ /* See if this jump conditionally branches around an unconditional
+ jump. If so, invert this jump and point it to the target of the
second jump. */
if (next && JUMP_P (next)
+ && any_condjump_p (insn)
&& (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)
&& target_label
&& next_active_insn (target_label) == next_active_insn (next)
@@ -3172,7 +3173,7 @@ relax_delay_slots (rtx first)
if (JUMP_P (insn)
&& (simplejump_p (insn) || GET_CODE (PATTERN (insn)) == RETURN)
&& (other = prev_active_insn (insn)) != 0
- && (condjump_p (other) || condjump_in_parallel_p (other))
+ && any_condjump_p (other)
&& no_labels_between_p (other, insn)
&& 0 > mostly_true_jump (other,
get_branch_condition (other,
--- gcc/testsuite/g++.dg/opt/pr23454.C.jj 2005-09-01 20:42:06.000000000 +0200
+++ gcc/testsuite/g++.dg/opt/pr23454.C 2005-09-01 20:40:43.000000000 +0200
@@ -0,0 +1,41 @@
+/* PR rtl-optimization/23454 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void foo ();
+int a, b;
+char c;
+long long d, e;
+
+static inline int
+bar (const long long s, const long long t)
+{
+ return ((s < t) ? -1 : s > t ? 1 : 0);
+}
+
+int fn ();
+int f;
+
+void
+baz (int x)
+{
+ long long g = fn ();
+ if (f)
+ {
+ b++;
+ return;
+ }
+ if (g == 0)
+ a++;
+ if (x)
+ foo ();
+ if (!c)
+ c = 1;
+ else if (g != 0)
+ {
+ if (bar (g, d) < 0)
+ d = g;
+ if (bar (g, e) > 0)
+ e = g;
+ }
+}
Jakub