aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2015-02-04 14:23:47 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2015-02-04 14:23:47 +0000
commitaf9f5d95df023eab3779878815bc2ad09870f36e (patch)
tree6e157abd20a27c5839f432d59185a44538a8581a
parenta720f0efffdf29c2f486e3d825446be4aa77b375 (diff)
downloadgcc-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/ChangeLog4
-rw-r--r--gcc/simplify-rtx.c33
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)