OSDN Git Service

* simplify-rtx.c (simplify_unary_operation_1) <POPCOUNT>: We can
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Feb 2007 17:10:56 +0000 (17:10 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Feb 2007 17:10:56 +0000 (17:10 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121716 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/builtin-bswap-2.c [new file with mode: 0644]

index f4e45df..3a185dc 100644 (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>
 
        PR 30562
 2007-02-08  Diego Novillo  <dnovillo@redhat.com>
 
        PR 30562
index f04f052..8d8bbe5 100644 (file)
@@ -790,11 +790,54 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
       break;
 
     case POPCOUNT:
       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:
     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:
       break;
 
     case FLOAT:
@@ -1047,7 +1090,19 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
          break;
 
        case BSWAP:
          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;
 
        case TRUNCATE:
          val = arg0;
@@ -1195,6 +1250,30 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
          lv &= 1;
          break;
 
          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;
        case TRUNCATE:
          /* This is just a change-of-mode, so do nothing.  */
          lv = l1, hv = h1;
index 8454452..e5195cb 100644 (file)
@@ -1,5 +1,9 @@
 2007-02-08  Roger Sayle  <roger@eyesopen.com>
 
 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.
 
        * 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 (file)
index 0000000..818aa76
--- /dev/null
@@ -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);
+}
+