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:
parent
2757d5ecfc
commit
54833ec0a6
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
14
gcc/testsuite/gcc.target/arm/xor-and.c
Normal file
14
gcc/testsuite/gcc.target/arm/xor-and.c
Normal 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" } } */
|
Loading…
Reference in New Issue
Block a user