[PATCH] Robustify add_reg_br_prob_note (PR middle-end/28683)

Jakub Jelinek jakub@redhat.com
Wed Aug 23 19:58:00 GMT 2006


Hi!

On this testcase the tree optimizers have not done a very good job,
have not optimized (void *) (&r->f) == (void *) r into 1 and GCC discovers
that only when expanding into rtl.  While it would be better if this was
caught earlier, I think we can't rule the RTL expanders ever finding
something that can be optimized and wasn't optimized out already at the tree
level.  In this case, on x86_64 and i386
if (i == 0 && &r->f == r) ; else goto label;
is optimized into:
(insn 11 9 12 (set (reg:CCZ 17 flags)
        (compare:CCZ (mem/c/i:SI (symbol_ref:DI ("i.1877") [flags 0x2] <var_decl 0xf7dca8c0 i>) [4 i+0 S4 A32])
            (const_int 0 [0x0]))) -1 (nil)
    (nil))

(jump_insn 12 11 13 (set (pc)
        (if_then_else (ne (reg:CCZ 17 flags)
                (const_int 0 [0x0]))
            (label_ref 0)
            (pc))) -1 (nil)
    (nil))

(jump_insn 13 12 14 (set (pc)
        (label_ref 0)) -1 (nil)
    (nil))

(barrier 14 13 0)

and subsequent RTL optimizations would optimize it (e.g. drop insns 11 and 12).
But we first add_reg_br_prob_note on this and it has quite fragile check
if it sees a conditional jump around unconditional, which assumes that if
there is a conditional jump followed by unconditional jump, it must have
at least 2 following insns, which isn't true in the above case.
The following patch robustifies that test.

Ok for trunk and 4.1?

2006-08-23  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/28683
	* cfgexpand.c (add_reg_br_prob_note): Check if last has exactly
	3 following insns.

	* gcc.c-torture/compile/20060823-1.c: New test.

--- gcc/testsuite/gcc.c-torture/compile/20060823-1.c.jj	2006-08-23 19:35:53.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/compile/20060823-1.c	2006-08-23 19:37:34.000000000 +0200
@@ -0,0 +1,18 @@
+/* PR middle-end/28683 */
+
+extern void foo (int *);
+
+struct A
+{
+  int f;
+};
+
+struct A *
+test (struct A *r)
+{
+  int *f = &r->f;
+  static int i = 0;
+  if (!i && !((void *) f == (void *) r))
+    foo (&i);
+  return r;
+}
--- gcc/cfgexpand.c.jj	2006-08-23 18:31:24.000000000 +0200
+++ gcc/cfgexpand.c	2006-08-23 19:24:30.000000000 +0200
@@ -58,7 +58,9 @@ add_reg_br_prob_note (rtx last, int prob
 	if (!any_condjump_p (last)
 	    || !JUMP_P (NEXT_INSN (last))
 	    || !simplejump_p (NEXT_INSN (last))
+	    || !NEXT_INSN (NEXT_INSN (last))
 	    || !BARRIER_P (NEXT_INSN (NEXT_INSN (last)))
+	    || !NEXT_INSN (NEXT_INSN (NEXT_INSN (last)))
 	    || !LABEL_P (NEXT_INSN (NEXT_INSN (NEXT_INSN (last))))
 	    || NEXT_INSN (NEXT_INSN (NEXT_INSN (NEXT_INSN (last)))))
 	  goto failed;

	Jakub



More information about the Gcc-patches mailing list