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:
parent
d37d06fef8
commit
9f05adb09f
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
10
gcc/testsuite/gcc.target/i386/builtin-bswap-2.c
Normal file
10
gcc/testsuite/gcc.target/i386/builtin-bswap-2.c
Normal 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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user