This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Robustify add_reg_br_prob_note (PR middle-end/28683)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 23 Aug 2006 13:53:53 -0400
- Subject: [PATCH] Robustify add_reg_br_prob_note (PR middle-end/28683)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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