diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5067ae1a9e5..73c0c366812 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2009-06-23 Andreas Krebbel + + * 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 * sdbout.c (sdbout_one_type): Fix braces in switch. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7dbb38fcff8..7158684ca12 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-06-23 Andreas Krebbel + + * gcc.dg/optimize-bswapsi-1.c: Add new bswap implementation. + * gcc.dg/optimize-bswapdi-1.c: Likewise. + 2009-06-22 Adam Nemet * 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 45fb2af2b30..449dc19f765 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 fc77296d522..7b27b930838 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 7e4e1bd5eb6..20ddbad5e55 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;