diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2015-02-04 14:23:47 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2015-02-04 14:23:47 +0000 |
commit | af9f5d95df023eab3779878815bc2ad09870f36e (patch) | |
tree | 6e157abd20a27c5839f432d59185a44538a8581a | |
parent | a720f0efffdf29c2f486e3d825446be4aa77b375 (diff) | |
download | gcc-af9f5d95df023eab3779878815bc2ad09870f36e.zip gcc-af9f5d95df023eab3779878815bc2ad09870f36e.tar.gz gcc-af9f5d95df023eab3779878815bc2ad09870f36e.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 33 |
2 files changed, 37 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 685f4b8..977e208 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,10 @@ 2015-02-04 Alexandre Oliva <aoliva@redhat.com> 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 committing to a simplification. diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index bea9ec3..04452c6 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) |