aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/optimize-bswapdi-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/optimize-bswapsi-1.c18
-rw-r--r--gcc/tree-ssa-math-opts.c7
5 files changed, 54 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5067ae1..73c0c36 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-23 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * tree-ssa-math-opts.c (find_bswap): Increase the search depth in
+ order to match bswaps with signed source operands.
+
2009-06-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
* sdbout.c (sdbout_one_type): Fix braces in switch.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7dbb38f..7158684 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-23 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * gcc.dg/optimize-bswapsi-1.c: Add new bswap implementation.
+ * gcc.dg/optimize-bswapdi-1.c: Likewise.
+
2009-06-22 Adam Nemet <anemet@caviumnetworks.com>
* gcc.target/mips/truncate-3.c: New test.
diff --git a/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c
index 45fb2af..449dc19 100644
--- a/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c
+++ b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c
@@ -24,5 +24,25 @@ swap64 (uint64_t in)
return __const_swab64 (in);
}
-/* { dg-final { scan-tree-dump-times "64 bit bswap implementation found at" 1 "bswap" } } */
+/* This variant is currently used by libgcc. The difference is that
+ the bswap source and destination have a signed integer type which
+ requires a slightly higher search depth in order to dive through
+ the cast as well. */
+
+typedef int DItype __attribute__ ((mode (DI)));
+DItype
+swap64_b (DItype u)
+{
+ return ((((u) & 0xff00000000000000ull) >> 56)
+ | (((u) & 0x00ff000000000000ull) >> 40)
+ | (((u) & 0x0000ff0000000000ull) >> 24)
+ | (((u) & 0x000000ff00000000ull) >> 8)
+ | (((u) & 0x00000000ff000000ull) << 8)
+ | (((u) & 0x0000000000ff0000ull) << 24)
+ | (((u) & 0x000000000000ff00ull) << 40)
+ | (((u) & 0x00000000000000ffull) << 56));
+}
+
+
+/* { dg-final { scan-tree-dump-times "64 bit bswap implementation found at" 2 "bswap" } } */
/* { dg-final { cleanup-tree-dump "bswap" } } */
diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c
index fc77296..7b27b93 100644
--- a/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c
+++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c
@@ -31,5 +31,21 @@ swap32_b (uint32_t in)
return a;
}
-/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 2 "bswap" } } */
+/* This variant is currently used by libgcc. The difference is that
+ the bswap source and destination have a signed integer type which
+ requires a slightly higher search depth in order to dive through
+ the cast as well. */
+
+typedef int SItype __attribute__ ((mode (SI)));
+
+SItype
+swap32_c (SItype u)
+{
+ return ((((u) & 0xff000000) >> 24)
+ | (((u) & 0x00ff0000) >> 8)
+ | (((u) & 0x0000ff00) << 8)
+ | (((u) & 0x000000ff) << 24));
+}
+
+/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 3 "bswap" } } */
/* { dg-final { cleanup-tree-dump "bswap" } } */
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 7e4e1bd..20ddbad 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1125,9 +1125,14 @@ find_bswap (gimple stmt)
struct symbolic_number n;
tree source_expr;
+ /* The last parameter determines the depth search limit. It usually
+ correlates directly to the number of bytes to be touched. We
+ increase that number by one here in order to also cover signed ->
+ unsigned conversions of the src operand as can be seen in
+ libgcc. */
source_expr = find_bswap_1 (stmt, &n,
TREE_INT_CST_LOW (
- TYPE_SIZE_UNIT (gimple_expr_type (stmt))));
+ TYPE_SIZE_UNIT (gimple_expr_type (stmt))) + 1);
if (!source_expr)
return NULL_TREE;