This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix incorrect byte swap detection (PR tree-optimization/60454)
- From: "Thomas Preud'homme" <thomas dot preudhomme at arm dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 7 Mar 2014 17:35:01 +0800
- Subject: [PATCH] Fix incorrect byte swap detection (PR tree-optimization/60454)
- Authentication-results: sourceware.org; auth=none
The bswap optimization has a bug where a code can be incorrectly detected as doing a byte swap, therefore leading to change of behavior for the program compiled. This is tracked as PR60454. The patch below fixes the issue.
Best regards,
Thomas Preud'homme
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 748805e..b6d7d93 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-03-07 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
+ PR tree-optimization/60454
+ * tree-ssa-math-opts.c (find_bswap_1): Fix bswap detection.
+
2014-02-23 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/microblaze.md: Correct ashrsi_reg / lshrsi_reg names
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f3c0c85..d3e0385 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-03-07 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
+ PR tree-optimization/60454
+ * gcc.dg/optimize-bswapsi-2.c (fake_swap32): Testcase to track
+ regression of PR60454.
+
2014-02-23 David Holsgrove <david.holsgrove@xilinx.com>
* gcc/testsuite/gcc.target/microblaze/others/mem_reload.c: New test.
diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-2.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-2.c
new file mode 100644
index 0000000..f20269e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-2.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target arm*-*-* alpha*-*-* i?86-*-* powerpc*-*-* rs6000-*-* x86_64-*-* s390*-*-* } } */
+/* { dg-require-effective-target stdint_types } */
+/* { dg-options "-O2 -fdump-tree-bswap" } */
+/* { dg-options "-O2 -fdump-tree-bswap -march=z900" { target s390-*-* } } */
+
+#include <stdint.h>
+
+#define __fake_const_swab32(x) ((uint32_t)( \
+ (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
+ (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
+ (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 8) | \
+ (((uint32_t)(x) & (uint32_t)0x0000ff00UL) ) | \
+ (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
+
+/* Previous version of bswap optimization would detect byte swap when none
+ happen. This test aims at catching such wrong detection to avoid
+ regressions. */
+
+uint32_t
+fake_swap32 (uint32_t in)
+{
+ return __fake_const_swab32 (in);
+}
+
+/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 0 "bswap" } } */
+/* { dg-final { cleanup-tree-dump "bswap" } } */
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 8e372ed..10a11ec 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1801,7 +1801,9 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit)
if (rhs_class == GIMPLE_BINARY_RHS)
{
+ int i;
struct symbolic_number n1, n2;
+ unsigned HOST_WIDEST_INT mask;
tree source_expr2;
if (code != BIT_IOR_EXPR)
@@ -1827,6 +1829,15 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit)
return NULL_TREE;
n->size = n1.size;
+ for (i = 0, mask = 0xff; i < n->size; i++, mask <<= 8)
+ {
+ unsigned HOST_WIDEST_INT masked1, masked2;
+
+ masked1 = n1.n & mask;
+ masked2 = n2.n & mask;
+ if (masked1 && masked2 && masked1 != masked2)
+ return NULL_TREE;
+ }
n->n = n1.n | n2.n;
if (!verify_symbolic_number_p (n, stmt))