[backport from gcc-4.7/trunk <mikpe@it.uu.se>]

gcc/

2011-10-28  Chung-Lin Tang  <cltang@codesourcery.com>

	PR rtl-optimization/49720
	* simplify-rtx.c (simplify_relational_operation_1): Detect
	infinite recursion condition in "(eq/ne (plus x cst1) cst2)
	simplifies to (eq/ne x (cst2 - cst1))" case.

gcc/testsuite/

2011-10-28  Chung-Lin Tang  <cltang@codesourcery.com>

	PR rtl-optimization/49720
	* g++.dg/torture/pr49720.C: New test.

--- gcc-4.6.2/gcc/simplify-rtx.c.~1~	2011-07-04 23:09:26.000000000 +0200
+++ gcc-4.6.2/gcc/simplify-rtx.c	2011-11-05 12:59:21.000000000 +0100
@@ -4177,10 +4177,20 @@ simplify_relational_operation_1 (enum rt
     {
       rtx x = XEXP (op0, 0);
       rtx c = XEXP (op0, 1);
+      enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
+      rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
 
-      c = simplify_gen_binary (op0code == PLUS ? MINUS : PLUS,
-			       cmp_mode, op1, c);
-      return simplify_gen_relational (code, mode, cmp_mode, x, c);
+      /* Detect an infinite recursive condition, where we oscillate at this
+	 simplification case between:
+	    A + B == C  <--->  C - B == A,
+	 where A, B, and C are all constants with non-simplifiable expressions,
+	 usually SYMBOL_REFs.  */
+      if (GET_CODE (tem) == invcode
+	  && CONSTANT_P (x)
+	  && rtx_equal_p (c, XEXP (tem, 1)))
+	return NULL_RTX;
+
+      return simplify_gen_relational (code, mode, cmp_mode, x, tem);
     }
 
   /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
--- gcc-4.6.2/gcc/testsuite/g++.dg/torture/pr49720.C.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.6.2/gcc/testsuite/g++.dg/torture/pr49720.C	2011-11-05 12:59:21.000000000 +0100
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+extern char t_start[], t_end[], t_size[];
+bool foo (void)
+{
+  long size = reinterpret_cast<long>(t_size);
+  return (size == t_end - t_start);
+}
