summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2007-02-08 17:10:56 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2007-02-08 17:10:56 +0000
commit9f05adb09fd35252136f4d28182e5d60cc03fb36 (patch)
tree048a2641bea241f51fef4600e4852357f5c9e51e /gcc
parentd37d06fef83c5f8355fa327d5fa0ff25cd31bb77 (diff)
downloadgcc-9f05adb09fd35252136f4d28182e5d60cc03fb36.tar.gz
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/simplify-rtx.c89
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-bswap-2.c10
4 files changed, 108 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f4e45dfb25d..3a185dc06b8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
PR 30562
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index f04f0521e35..8d8bbe52d0c 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -790,11 +790,54 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
break;
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:
- /* (pop* (zero_extend <X>)) = (pop* <X>) */
- if (GET_CODE (op) == ZERO_EXTEND)
- return simplify_gen_unary (code, mode, XEXP (op, 0),
- GET_MODE (XEXP (op, 0)));
+ switch (GET_CODE (op))
+ {
+ case NOT:
+ 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;
case FLOAT:
@@ -1047,7 +1090,19 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
break;
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:
val = arg0;
@@ -1195,6 +1250,30 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
lv &= 1;
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:
/* This is just a change-of-mode, so do nothing. */
lv = l1, hv = h1;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8454452f303..e5195cb2e98 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
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>
+
* gfortran.dg/forall_8.f90: New test case.
* gfortran.dg/forall_9.f90: Likewise.
diff --git a/gcc/testsuite/gcc.target/i386/builtin-bswap-2.c b/gcc/testsuite/gcc.target/i386/builtin-bswap-2.c
new file mode 100644
index 00000000000..818aa76b95d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-bswap-2.c
@@ -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);
+}
+