https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90323

--- Comment #11 from luoxhu at gcc dot gnu.org ---
I noticed that you added the below optimization with commit
a62436c0a505155fc8becac07a8c0abe2c265bfe. But it doesn't even handle this case,
cse1 pass will call simplify_binary_operation_1, both op0 and op1 are REGs
instead of AND operators, do you have a test case to cover that piece of code?

__attribute__ ((noinline))
 long without_sel3( long l,  long r) {
    long tmp = {0x0ff00fff};
    l =  ( (l ^ r) & tmp) ^ l;
    return l;
}


without_sel3:
        xor 4,3,4
        rlwinm 4,4,0,20,11
        rldicl 4,4,0,36
        xor 3,4,3
        blr
        .long 0
        .byte 0,0,0,0,0,0,0,0


+2016-11-09  Segher Boessenkool  <seg...@kernel.crashing.org>
+
+       * simplify-rtx.c (simplify_binary_operation_1): Simplify
+       (xor (and (xor A B) C) B) to (ior (and A C) (and B ~C)) and
+       (xor (and (xor A B) C) A) to (ior (and A ~C) (and B C)) if C
+       is a const_int.

diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 5c3dea1a349..11a2e0267c7 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2886,6 +2886,37 @@ simplify_binary_operation_1 (enum rtx_code code,
machine_mode mode,
            }
        }

+      /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
+        do (ior (and A ~C) (and B C)) which is a machine instruction on some
+        machines, and also has shorter instruction path length.  */
+      if (GET_CODE (op0) == AND
+         && GET_CODE (XEXP (op0, 0)) == XOR
+         && CONST_INT_P (XEXP (op0, 1))
+         && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
+       {
+         rtx a = trueop1;
+         rtx b = XEXP (XEXP (op0, 0), 1);
+         rtx c = XEXP (op0, 1);
+         rtx nc = simplify_gen_unary (NOT, mode, c, mode);
+         rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
+         rtx bc = simplify_gen_binary (AND, mode, b, c);
+         return simplify_gen_binary (IOR, mode, a_nc, bc);
+       }
+      /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) 
*/
+      else if (GET_CODE (op0) == AND
+         && GET_CODE (XEXP (op0, 0)) == XOR
+         && CONST_INT_P (XEXP (op0, 1))
+         && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
+       {
+         rtx a = XEXP (XEXP (op0, 0), 0);
+         rtx b = trueop1;
+         rtx c = XEXP (op0, 1);
+         rtx nc = simplify_gen_unary (NOT, mode, c, mode);
+         rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
+         rtx ac = simplify_gen_binary (AND, mode, a, c);
+         return simplify_gen_binary (IOR, mode, ac, b_nc);
+       }

Reply via email to