simplify-rtx.c (simplify_unary_operation_1): We can strip zero_extend, bswap and rotates from POCOUNT's argument.

* simplify-rtx.c (simplify_unary_operation_1) <POPCOUNT>: We can
	strip zero_extend, bswap and rotates from POCOUNT's argument.
	<PARITY>: Likewise, we can strip not, bswap, sign_extend,
	zero_extend and rotates from PARITY's argument.
	<BSWAP>: A byte-swap followed by a byte-swap is an identity.
	(simplify_const_unary_operation) <BSWAP>: Evaluate the byte-swap
	of an integer constant at compile-time.

	* gcc.target/i386/builtin-bswap-2.c: New test case.

From-SVN: r121716
This commit is contained in:
Roger Sayle 2007-02-08 17:10:56 +00:00 committed by Roger Sayle
parent d37d06fef8
commit 9f05adb09f
4 changed files with 108 additions and 5 deletions

View File

@ -1,3 +1,13 @@
2007-02-08 Roger Sayle <roger@eyesopen.com>
* simplify-rtx.c (simplify_unary_operation_1) <POPCOUNT>: We can
strip zero_extend, bswap and rotates from POCOUNT's argument.
<PARITY>: Likewise, we can strip not, bswap, sign_extend,
zero_extend and rotates from PARITY's argument.
<BSWAP>: A byte-swap followed by a byte-swap is an identity.
(simplify_const_unary_operation) <BSWAP>: Evaluate the byte-swap
of an integer constant at compile-time.
2007-02-08 Diego Novillo <dnovillo@redhat.com> 2007-02-08 Diego Novillo <dnovillo@redhat.com>
PR 30562 PR 30562

View File

@ -790,11 +790,54 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
break; break;
case POPCOUNT: case POPCOUNT:
switch (GET_CODE (op))
{
case BSWAP:
case ZERO_EXTEND:
/* (popcount (zero_extend <X>)) = (popcount <X>) */
return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
GET_MODE (XEXP (op, 0)));
case ROTATE:
case ROTATERT:
/* Rotations don't affect popcount. */
if (!side_effects_p (XEXP (op, 1)))
return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
GET_MODE (XEXP (op, 0)));
break;
default:
break;
}
break;
case PARITY: case PARITY:
/* (pop* (zero_extend <X>)) = (pop* <X>) */ switch (GET_CODE (op))
if (GET_CODE (op) == ZERO_EXTEND) {
return simplify_gen_unary (code, mode, XEXP (op, 0), case NOT:
GET_MODE (XEXP (op, 0))); case BSWAP:
case ZERO_EXTEND:
case SIGN_EXTEND:
return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
GET_MODE (XEXP (op, 0)));
case ROTATE:
case ROTATERT:
/* Rotations don't affect parity. */
if (!side_effects_p (XEXP (op, 1)))
return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
GET_MODE (XEXP (op, 0)));
break;
default:
break;
}
break;
case BSWAP:
/* (bswap (bswap x)) -> x. */
if (GET_CODE (op) == BSWAP)
return XEXP (op, 0);
break; break;
case FLOAT: case FLOAT:
@ -1047,7 +1090,19 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
break; break;
case BSWAP: case BSWAP:
return 0; {
unsigned int s;
val = 0;
for (s = 0; s < width; s += 8)
{
unsigned int d = width - s - 8;
unsigned HOST_WIDE_INT byte;
byte = (arg0 >> s) & 0xff;
val |= byte << d;
}
}
break;
case TRUNCATE: case TRUNCATE:
val = arg0; val = arg0;
@ -1195,6 +1250,30 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
lv &= 1; lv &= 1;
break; break;
case BSWAP:
{
unsigned int s;
hv = 0;
lv = 0;
for (s = 0; s < width; s += 8)
{
unsigned int d = width - s - 8;
unsigned HOST_WIDE_INT byte;
if (s < HOST_BITS_PER_WIDE_INT)
byte = (l1 >> s) & 0xff;
else
byte = (h1 >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
if (d < HOST_BITS_PER_WIDE_INT)
lv |= byte << d;
else
hv |= byte << (d - HOST_BITS_PER_WIDE_INT);
}
}
break;
case TRUNCATE: case TRUNCATE:
/* This is just a change-of-mode, so do nothing. */ /* This is just a change-of-mode, so do nothing. */
lv = l1, hv = h1; lv = l1, hv = h1;

View File

@ -1,3 +1,7 @@
2007-02-08 Roger Sayle <roger@eyesopen.com>
* gcc.target/i386/builtin-bswap-2.c: New test case.
2007-02-08 Roger Sayle <roger@eyesopen.com> 2007-02-08 Roger Sayle <roger@eyesopen.com>
* gfortran.dg/forall_8.f90: New test case. * gfortran.dg/forall_8.f90: New test case.

View File

@ -0,0 +1,10 @@
/* { dg-do compile } */
/* { dg-options "-O2 -march=nocona" } */
/* { dg-final { scan-assembler-not "bswap\[ \t\]" } } */
int foo(int x)
{
int t = __builtin_bswap32 (x);
return __builtin_bswap32 (t);
}