simplify-rtx.c (simplify_binary_operation_1): Handle (xor (and A B) C) case when B and C are both constants.

2011-03-21  Chung-Lin Tang  <cltang@codesourcery.com>

	* simplify-rtx.c (simplify_binary_operation_1): Handle
	(xor (and A B) C) case when B and C are both constants.

	testsuite/
	* gcc.target/arm/xor-and.c: New.

From-SVN: r171208
This commit is contained in:
Chung-Lin Tang 2011-03-21 07:27:03 +00:00 committed by Chung-Lin Tang
parent 2757d5ecfc
commit 54833ec0a6
4 changed files with 63 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2011-03-21 Chung-Lin Tang <cltang@codesourcery.com>
* simplify-rtx.c (simplify_binary_operation_1): Handle
(xor (and A B) C) case when B and C are both constants.
2011-03-21 Mingjie Xing <mingjie.xing@gmail.com>
* tree-dfa.c (add_referenced_var): Fix typo in comment.

View File

@ -2480,6 +2480,46 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
XEXP (op0, 1), mode),
op1);
/* 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)
== (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
== ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
Attempt a few simplifications when B and C are both constants. */
if (GET_CODE (op0) == AND
&& CONST_INT_P (op1)
&& CONST_INT_P (XEXP (op0, 1)))
{
rtx a = XEXP (op0, 0);
rtx b = XEXP (op0, 1);
rtx c = op1;
HOST_WIDE_INT bval = INTVAL (b);
HOST_WIDE_INT cval = INTVAL (c);
rtx na_c
= simplify_binary_operation (AND, mode,
simplify_gen_unary (NOT, mode, a, mode),
c);
if ((~cval & bval) == 0)
{
/* Try to simplify ~A&C | ~B&C. */
if (na_c != NULL_RTX)
return simplify_gen_binary (IOR, mode, na_c,
GEN_INT (~bval & cval));
}
else
{
/* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
if (na_c == const0_rtx)
{
rtx a_nc_b = simplify_gen_binary (AND, mode, a,
GEN_INT (~cval & bval));
return simplify_gen_binary (IOR, mode, a_nc_b,
GEN_INT (~bval & cval));
}
}
}
/* (xor (comparison foo bar) (const_int 1)) can become the reversed
comparison if STORE_FLAG_VALUE is 1. */
if (STORE_FLAG_VALUE == 1

View File

@ -1,3 +1,7 @@
2011-03-21 Chung-Lin Tang <cltang@codesourcery.com>
* gcc.target/arm/xor-and.c: New.
2010-03-21 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/22572

View File

@ -0,0 +1,14 @@
/* { dg-do compile } */
/* { dg-options "-O -march=armv6" } */
unsigned short foo (unsigned short x)
{
x ^= 0x4002;
x >>= 1;
x |= 0x8000;
return x;
}
/* { dg-final { scan-assembler "orr" } } */
/* { dg-final { scan-assembler-not "mvn" } } */
/* { dg-final { scan-assembler-not "uxth" } } */