This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/13521
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, Gabriel Dos Reis <gdr at integrable-solutions dot net>
- Cc: jh at suse dot cz, gcc-patches at gcc dot gnu dot org
- Date: Wed, 31 Dec 2003 11:05:54 +0100
- Subject: [PATCH] Fix PR optimization/13521
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Without this patch insns_match_p would on the following testcase
on AMD64 target at -O2 and higher replace REG_EQUAL after reload and
crossjump:
(code_label:HI 264 96 214 9 27 "" [1 uses])
(note:HI 214 264 31 9 [bb 9] NOTE_INSN_BASIC_BLOCK)
(note:HI 31 214 35 9 ("N.i") 20)
(insn:HI 35 31 36 9 0x40284840 (set (reg:SI 1 edx [58])
(const_int -1 [0xffffffffffffffff])) 44 {*movsi_1} (nil)
(expr_list:REG_DEAD (reg:SI 0 eax [67])
(expr_list:REG_EQUAL (const_int -1 [0xffffffffffffffff])
(nil))))
(jump_insn:HI 36 35 37 9 0x40284840 (set (pc)
(label_ref 204)) 515 {jump} (nil)
(nil))
---------
(code_label:HI 265 37 233 10 28 "" [1 uses])
(note:HI 233 265 130 10 [bb 10] NOTE_INSN_BASIC_BLOCK)
(note:HI 130 233 134 10 ("N.i") 40)
(insn:HI 134 130 135 10 0x40284840 (set (reg:SI 1 edx [58])
(const_int -1 [0xffffffffffffffff])) 44 {*movsi_1} (nil)
(expr_list:REG_DEAD (reg:SI 43 r14d [81])
(expr_list:REG_EQUAL (const_int -1 [0xffffffffffffffff])
(nil))))
(jump_insn:HI 135 134 136 10 0x40284840 (set (pc)
(label_ref 204)) 515 {jump} (nil)
(nil))
into the latter. This later causes endless loop in
calculate_global_regs_live because %r14d is set only in some predecessors
of this BB and not in others.
Ok for 3.3 branch?
Ok for mainline (just the testcase)?
2003-12-31 Jakub Jelinek <jakub@redhat.com>
PR optimization/13521
Backport from mainline:
2003-03-22 Richard Henderson <rth@redhat.com>
* cfgcleanup.c (insns_match_p): Do not do EQUIV substitution
after reload.
* gcc.c-torture/compile/20031231-1.c: New test.
--- gcc/cfgcleanup.c.jj 2003-09-16 17:25:32.000000000 +0200
+++ gcc/cfgcleanup.c 2003-12-31 12:59:57.000000000 +0100
@@ -974,7 +974,15 @@ insns_match_p (mode, i1, i2)
#endif
if (reload_completed
- ? ! rtx_renumbered_equal_p (p1, p2) : ! rtx_equal_p (p1, p2))
+ ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
+ return true;
+
+ /* Do not do EQUIV substitution after reload. First, we're undoing the
+ work of reload_cse. Second, we may be undoing the work of the post-
+ reload splitting pass. */
+ /* ??? Possibly add a new phase switch variable that can be used by
+ targets to disallow the troublesome insns after splitting. */
+ if (!reload_completed)
{
/* The following code helps take care of G++ cleanups. */
rtx equiv1 = find_reg_equal_equiv_note (i1);
@@ -1001,11 +1009,9 @@ insns_match_p (mode, i1, i2)
return true;
}
}
-
- return false;
}
- return true;
+ return false;
}
/* Look through the insns at the end of BB1 and BB2 and find the longest
--- gcc/testsuite/gcc.c-torture/compile/20031231-1.c.jj 2003-12-31 13:03:32.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/20031231-1.c 2003-12-29 16:34:47.000000000 +0100
@@ -0,0 +1,51 @@
+extern int f1 (int, void *);
+extern int *f2 (void) __attribute__ ((__const__));
+extern int f3 (int, void *);
+
+int
+test (int x, char *y, int z)
+{
+ int b = 0;
+
+ if (x < 1024)
+ {
+ y[0] = '\0';
+
+ do
+ {
+ switch (f1 (x, y + b))
+ {
+ case -1:
+ if (b == 0)
+ return -1;
+ else
+ return b;
+
+ default:
+ b++;
+ }
+ }
+ while (y[b - 1] != '\0' && y[b - 1] != '\n' && b < z);
+ }
+ else
+ {
+ do
+ {
+ switch (f3 (x, y + b))
+ {
+ case -1:
+ if ((*f2 ()) == 4)
+ continue;
+ if (b == 0)
+ return -1;
+ else
+ return b;
+
+ default:
+ b++;
+ }
+ }
+ while (y[b - 1] != '\0' && y[b - 1] != '\n' && b < z);
+ }
+ return b;
+}
Jakub