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  <ja...@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

Reply via email to