This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR optimization/13521


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]