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]

[committed] Fix recent simplify_binary_operation_1 bug (PR rtl-optimization/64957)


Hi!

The
      /* Given (xor (ior (xor A B) C) D), where B, C and D are
         constants, simplify to (xor (ior A C) (B&~C)^D), canceling
         out bits inverted twice and not set by C.  Similarly, given
         (xor (and (xor A B) C) D), simplify without inverting C in
         the xor operand: (xor (and A C) (B&C)^D).
      */
comment describes the intended optimization correctly, but unfortunately
the code diverges from it, using (xor (and A C) (B&~C)^D)
for the second and (xor (ior A C) (B&C)^D) for the first one.

Fixed thusly, committed as obvious after bootstrapping/regtesting it on
x86_64-linux and i686-linux.

2015-02-06  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/64957
	PR debug/64817
	* simplify-rtx.c (simplify_binary_operation_1): Use ~cval for
	IOR rather than for AND.

	* gcc.c-torture/execute/pr64957.c: New test.

--- gcc/simplify-rtx.c.jj	2015-02-04 15:24:20.000000000 +0100
+++ gcc/simplify-rtx.c	2015-02-06 09:41:31.139326554 +0100
@@ -2731,9 +2731,9 @@ simplify_binary_operation_1 (enum rtx_co
 	  HOST_WIDE_INT xcval;
 
 	  if (op == IOR)
-	    xcval = cval;
-	  else
 	    xcval = ~cval;
+	  else
+	    xcval = cval;
 
 	  return simplify_gen_binary (XOR, mode,
 				      simplify_gen_binary (op, mode, a, c),
--- gcc/testsuite/gcc.c-torture/execute/pr64957.c.jj	2015-02-06 09:43:12.595616710 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr64957.c	2015-02-06 09:43:26.361384715 +0100
@@ -0,0 +1,23 @@
+/* PR rtl-optimization/64957 */
+
+__attribute__((noinline, noclone)) int
+foo (int b)
+{
+  return (((b ^ 5) | 1) ^ 5) | 1;
+}
+
+__attribute__((noinline, noclone)) int
+bar (int b)
+{
+  return (((b ^ ~5) & ~1) ^ ~5) & ~1;
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    if (foo (i) != (i | 1) || bar (i) != (i & ~1))
+      __builtin_abort ();
+  return 0;
+}

	Jakub


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