re PR tree-optimization/63259 (Detecting byteswap sequence)
authorThomas Preud'homme <thomas.preudhomme@arm.com>
Fri, 31 Oct 2014 11:55:07 +0000 (11:55 +0000)
committerThomas Preud'homme <thopre01@gcc.gnu.org>
Fri, 31 Oct 2014 11:55:07 +0000 (11:55 +0000)
2014-10-31  Thomas Preud'homme  <thomas.preudhomme@arm.com>

    gcc/
    PR tree-optimization/63259
    * tree-ssa-math-opts.c (bswap_replace): Replace expression by a
    rotation left if it is a 16 bit byte swap.
    (pass_optimize_bswap::execute): Also consider bswap in LROTATE_EXPR
    and RROTATE_EXPR statements if it is a byte rotation.

    gcc/testsuite/
    PR tree-optimization/63259
    * optimize-bswapsi-1.c (swap32_f): New bswap pass test.
    * optimize-bswaphi-1.c: Drop useless SIType definition and fix typo in
    following comment.

From-SVN: r216971

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/optimize-bswaphi-1.c
gcc/testsuite/gcc.dg/optimize-bswapsi-1.c
gcc/tree-ssa-math-opts.c

index 5ffc217e6347c8a4719e8c7b6c87aba5604e5c61..f228610d0bb89034bfb3a44b112cc8a5969291b7 100644 (file)
@@ -1,3 +1,11 @@
+2014-10-31  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       PR tree-optimization/63259
+       * tree-ssa-math-opts.c (bswap_replace): Replace expression by a
+       rotation left if it is a 16 bit byte swap.
+       (pass_optimize_bswap::execute): Also consider bswap in LROTATE_EXPR
+       and RROTATE_EXPR statements if it is a byte rotation.
+
 2014-10-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR sanitizer/63697
index 7892292e078315a9e6feabb125ab2c48a46a2192..adc0e3e366d26b38a302a8df1f610f9db6fb8d59 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-31  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       PR tree-optimization/63259
+       * optimize-bswapsi-1.c (swap32_f): New bswap pass test.
+       * optimize-bswaphi-1.c: Drop useless SIType definition and fix typo in
+       following comment.
+
 2014-10-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR sanitizer/63697
index 18aba284e263bd34dd4fd3d51f46fe6a44407d34..692fceb951fb3fbe38110ef315d039890e5f8544 100644 (file)
@@ -42,11 +42,10 @@ uint32_t read_be16_3 (unsigned char *data)
   return *(data + 1) | (*data << 8);
 }
 
-typedef int SItype __attribute__ ((mode (SI)));
 typedef int HItype __attribute__ ((mode (HI)));
 
 /* Test that detection of significant sign extension works correctly. This
-   checks that unknown byte marker are set correctly in cast of cast.  */
+   checks that unknown byte markers are set correctly in cast of cast.  */
 
 HItype
 swap16 (HItype in)
index cfde2182e4cb0bc8de607744b5e95b9e0fdb8171..ad3ede492553e49aec752390748ce234e07a65fc 100644 (file)
@@ -78,5 +78,16 @@ swap32_e (SItype in)
         | (((in >> 24) & 0xFF) << 0);
 }
 
-/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 5 "bswap" } } */
+/* This variant comes from PR63259.  It compiles to a gimple sequence that ends
+   with a rotation instead of a bitwise OR.  */
+
+unsigned
+swap32_f (unsigned in)
+{
+  in = ((in & 0xff00ff00) >>  8) | ((in & 0x00ff00ff) <<  8);
+  in = ((in & 0xffff0000) >> 16) | ((in & 0x0000ffff) << 16);
+  return in;
+}
+
+/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 6 "bswap" } } */
 /* { dg-final { cleanup-tree-dump "bswap" } } */
index 5daeff26ab3fc8d0a8c448ebc1aeb3d410b4109f..27825895a272a4309e12dcbfa4ffe440a124b833 100644 (file)
@@ -2187,7 +2187,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
               struct symbolic_number *n, bool bswap)
 {
   tree src, tmp, tgt;
-  gimple call;
+  gimple bswap_stmt;
 
   src = gimple_assign_rhs1 (src_stmt);
   tgt = gimple_assign_lhs (cur_stmt);
@@ -2293,16 +2293,28 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
 
   tmp = src;
 
-  /* Convert the src expression if necessary.  */
-  if (!useless_type_conversion_p (TREE_TYPE (tmp), bswap_type))
+  /* Canonical form for 16 bit bswap is a rotate expression.  */
+  if (bswap && n->range == 16)
     {
-      gimple convert_stmt;
-      tmp = make_temp_ssa_name (bswap_type, NULL, "bswapsrc");
-      convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src, NULL);
-      gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
+      tree count = build_int_cst (NULL, BITS_PER_UNIT);
+      bswap_type = TREE_TYPE (src);
+      src = fold_build2 (LROTATE_EXPR, bswap_type, src, count);
+      bswap_stmt = gimple_build_assign (NULL, src);
     }
+  else
+    {
+      /* Convert the src expression if necessary.  */
+      if (!useless_type_conversion_p (TREE_TYPE (tmp), bswap_type))
+       {
+         gimple convert_stmt;
+         tmp = make_temp_ssa_name (bswap_type, NULL, "bswapsrc");
+         convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src,
+                                                      NULL);
+         gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
+       }
 
-  call = gimple_build_call (fndecl, 1, tmp);
+      bswap_stmt = gimple_build_call (fndecl, 1, tmp);
+    }
 
   tmp = tgt;
 
@@ -2315,7 +2327,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
       gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT);
     }
 
-  gimple_call_set_lhs (call, tmp);
+  gimple_set_lhs (bswap_stmt, tmp);
 
   if (dump_file)
     {
@@ -2324,7 +2336,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
       print_gimple_stmt (dump_file, cur_stmt, 0, 0);
     }
 
-  gsi_insert_after (&gsi, call, GSI_SAME_STMT);
+  gsi_insert_after (&gsi, bswap_stmt, GSI_SAME_STMT);
   gsi_remove (&gsi, true);
   return true;
 }
@@ -2388,13 +2400,29 @@ pass_optimize_bswap::execute (function *fun)
         {
          gimple src_stmt, cur_stmt = gsi_stmt (gsi);
          tree fndecl = NULL_TREE, bswap_type = NULL_TREE, load_type;
+         enum tree_code code;
          struct symbolic_number n;
          bool bswap;
 
-         if (!is_gimple_assign (cur_stmt)
-             || gimple_assign_rhs_code (cur_stmt) != BIT_IOR_EXPR)
+         if (!is_gimple_assign (cur_stmt))
            continue;
 
+         code = gimple_assign_rhs_code (cur_stmt);
+         switch (code)
+           {
+           case LROTATE_EXPR:
+           case RROTATE_EXPR:
+             if (!tree_fits_uhwi_p (gimple_assign_rhs2 (cur_stmt))
+                 || tree_to_uhwi (gimple_assign_rhs2 (cur_stmt))
+                    % BITS_PER_UNIT)
+               continue;
+             /* Fall through.  */
+           case BIT_IOR_EXPR:
+             break;
+           default:
+             continue;
+           }
+
          src_stmt = find_bswap_or_nop (cur_stmt, &n, &bswap);
 
          if (!src_stmt)