From af9f5d95df023eab3779878815bc2ad09870f36e Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Wed, 4 Feb 2015 14:23:47 +0000 Subject: [PATCH] Simplify XOR of (AND or IOR) of XOR. for gcc/ChangeLog PR debug/64817 * simplify-rtx.c (simplify_binary_operation_1): Simplify one of two XORs that have an intervening AND or IOR. From-SVN: r220405 --- gcc/ChangeLog | 4 ++++ gcc/simplify-rtx.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 685f4b8cfca..977e208052c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2015-02-04 Alexandre Oliva + PR debug/64817 + * simplify-rtx.c (simplify_binary_operation_1): Simplify one + of two XORs that have an intervening AND or IOR. + PR debug/64817 * simplify-rtx.c (simplify_binary_operation_1): Rewrite simplification of XOR of AND to not allocate new rtx before diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index bea9ec353f6..04452c6e447 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -2708,6 +2708,39 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, XEXP (op0, 1), mode), op1); + /* 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). + */ + else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND) + && GET_CODE (XEXP (op0, 0)) == XOR + && CONST_INT_P (op1) + && CONST_INT_P (XEXP (op0, 1)) + && CONST_INT_P (XEXP (XEXP (op0, 0), 1))) + { + enum rtx_code op = GET_CODE (op0); + rtx a = XEXP (XEXP (op0, 0), 0); + rtx b = XEXP (XEXP (op0, 0), 1); + rtx c = XEXP (op0, 1); + rtx d = op1; + HOST_WIDE_INT bval = INTVAL (b); + HOST_WIDE_INT cval = INTVAL (c); + HOST_WIDE_INT dval = INTVAL (d); + HOST_WIDE_INT xcval; + + if (op == IOR) + xcval = cval; + else + xcval = ~cval; + + return simplify_gen_binary (XOR, mode, + simplify_gen_binary (op, mode, a, c), + gen_int_mode ((bval & xcval) ^ dval, + mode)); + } + /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P), we can transform like this: (A&B)^C == ~(A&B)&C | ~C&(A&B) -- 2.30.2