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 up cprop to canonicalize PLUS/MINUS with 2 CONSTANT_P arguments (PR rtl-optimization/57915)


Hi!

Without this patch, cprop can propagate e.g. a SYMBOL_REF to former
(mem (plus (reg) (const_int)))
making it invalid RTL (as plus of CONSTANT_P arguments must be simplified
or surrounded by CONST).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2014-01-31  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/57915
	* recog.c (simplify_while_replacing): For PLUS/MINUS
	with both operands CONSTANT_P where one operand is equal
	to TO call simplify_gen_binary.

	* gcc.target/i386/pr57915.c: New test.

--- gcc/recog.c.jj	2014-01-23 10:53:05.000000000 +0100
+++ gcc/recog.c	2014-01-31 16:08:06.371826412 +0100
@@ -590,6 +590,14 @@ simplify_while_replacing (rtx *loc, rtx
 	validate_change (object, loc,
 			 simplify_gen_binary
 			 (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
+      /* Canonicalize addition of two constants, that must be either
+	 simplified into a constant or (const (plus (...) (...))).  */
+      else if (CONSTANT_P (XEXP (x, 0))
+	       && CONSTANT_P (XEXP (x, 1))
+	       && (XEXP (x, 0) == to || XEXP (x, 1) == to))
+	validate_change (object, loc,
+			 simplify_gen_binary
+			 (PLUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
       break;
     case MINUS:
       if (CONST_SCALAR_INT_P (XEXP (x, 1)))
@@ -599,6 +607,14 @@ simplify_while_replacing (rtx *loc, rtx
 			  simplify_gen_unary (NEG,
 					      GET_MODE (x), XEXP (x, 1),
 					      GET_MODE (x))), 1);
+      /* Canonicalize subtraction of two constants, that must be either
+	 simplified into a constant or (const (minus (...) (...))).  */
+      else if (CONSTANT_P (XEXP (x, 0))
+	       && CONSTANT_P (XEXP (x, 1))
+	       && (XEXP (x, 0) == to || XEXP (x, 1) == to))
+	validate_change (object, loc,
+			 simplify_gen_binary
+			 (MINUS, GET_MODE (x), XEXP (x, 0), XEXP (x, 1)), 1);
       break;
     case ZERO_EXTEND:
     case SIGN_EXTEND:
--- gcc/testsuite/gcc.target/i386/pr57915.c.jj	2014-01-31 16:10:47.436942155 +0100
+++ gcc/testsuite/gcc.target/i386/pr57915.c	2014-01-31 16:10:21.000000000 +0100
@@ -0,0 +1,33 @@
+/* PR rtl-optimization/57915 */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+extern struct T { char a[8]; char b[16]; } t;
+int c;
+void foo (void);
+
+extern inline char *
+baz (char *x, const char *y)
+{
+  const char *e = y;
+  unsigned long f, g;
+  asm ("" : "+c" (f), "+D" (e) : "a" ('\0'), "X" (*e));
+  g = e - 1 - y;
+  __builtin_memcpy (x, y, g);
+  x[g] = '\0';
+  return x;
+}
+
+void
+bar (void)
+{
+  char d[16];
+  baz (d, t.b);
+
+  for (;;)
+    {
+      foo ();
+      if (c)
+	baz (d, t.b);
+    }
+}

	Jakub


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