re PR tree-optimization/64718 (Bad 16-bit bswap replacement)
authorThomas Preud'homme <thomas.preudhomme@arm.com>
Wed, 28 Jan 2015 10:20:19 +0000 (10:20 +0000)
committerThomas Preud'homme <thopre01@gcc.gnu.org>
Wed, 28 Jan 2015 10:20:19 +0000 (10:20 +0000)
2015-01-28  Thomas Preud'homme  <thomas.preudhomme@arm.com>

    gcc/
    PR tree-optimization/64718
    * tree-ssa-math-opts.c (pass_optimize_bswap::execute): Make bswap_type
    be a 16bit unsigned integer when n->range is 16.
    (bswap_replace): Convert src to that type if necessary for all bswap
    sizes.  Fix rotation right notation in nearby comment.  Use bswap_type
    set in pass_optimize_bswap::execute ().

    gcc/testsuite/
    PR tree-optimization/64718
    * gcc.c-torture/execute/pr64718.c: New test.

From-SVN: r220203

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr64718.c [new file with mode: 0644]
gcc/tree-ssa-math-opts.c

index b5d0d2d19e6b1f46d502764e7b04d02dd5cdf9b5..71413471372326494ce111d32fc9876c003199be 100644 (file)
@@ -1,3 +1,12 @@
+2015-01-28  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       PR tree-optimization/64718
+       * tree-ssa-math-opts.c (pass_optimize_bswap::execute): Make bswap_type
+       be a 16bit unsigned integer when n->range is 16.
+       (bswap_replace): Convert src to that type if necessary for all bswap
+       sizes.  Fix rotation right notation in nearby comment.  Use bswap_type
+       set in pass_optimize_bswap::execute ().
+
 2015-01-28  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * config/aarch64/aarch64-simd.md (aarch64_abs<mode>): New.
index efa70174dfbe73dc9ca9eb947558a9fa81b11a10..4f4e72ca9f75379c00a2210c5757abd8697ea3e1 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-28  Thomas Preud'homme  <thomas.preudhomme@arm.com>
+
+       PR tree-optimization/64718
+       * gcc.c-torture/execute/pr64718.c: New test.
+
 2015-01-28  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * gcc.target/aarch64/abs_2.c: New.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64718.c b/gcc/testsuite/gcc.c-torture/execute/pr64718.c
new file mode 100644 (file)
index 0000000..58773e0
--- /dev/null
@@ -0,0 +1,18 @@
+static int __attribute__ ((noinline, noclone))
+swap (int x)
+{
+  return (unsigned short) ((unsigned short) x << 8 | (unsigned short) x >> 8);
+}
+
+static int a = 0x1234;
+
+int
+main (void)
+{
+  int b = 0x1234;
+  if (swap (a) != 0x3412)
+    __builtin_abort ();
+  if (swap (b) != 0x3412)
+    __builtin_abort ();
+  return 0;
+}
index 479f49f3a90996ba7dd3fcdab1590cd82e87d096..e30116dab1aab948c1aa59c0db49777f9c44c4ff 100644 (file)
@@ -2355,30 +2355,28 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type,
 
   tmp = src;
 
+  /* 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 (tmp, NOP_EXPR, src);
+      gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
+    }
+
   /* Canonical form for 16 bit bswap is a rotate expression.  Only 16bit values
      are considered as rotation of 2N bit values by N bits is generally not
-     equivalent to a bswap.  Consider for instance 0x01020304 >> 16 which gives
-     0x03040102 while a bswap for that value is 0x04030201.  */
+     equivalent to a bswap.  Consider for instance 0x01020304 r>> 16 which
+     gives 0x03040102 while a bswap for that value is 0x04030201.  */
   if (bswap && n->range == 16)
     {
       tree count = build_int_cst (NULL, BITS_PER_UNIT);
-      bswap_type = TREE_TYPE (src);
-      src = fold_build2 (LROTATE_EXPR, bswap_type, src, count);
+      src = fold_build2 (LROTATE_EXPR, bswap_type, tmp, 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 (tmp, NOP_EXPR, src);
-         gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
-       }
-
-      bswap_stmt = gimple_build_call (fndecl, 1, tmp);
-    }
+    bswap_stmt = gimple_build_call (fndecl, 1, tmp);
 
   tmp = tgt;
 
@@ -2386,6 +2384,7 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type,
   if (!useless_type_conversion_p (TREE_TYPE (tgt), bswap_type))
     {
       gimple convert_stmt;
+
       tmp = make_temp_ssa_name (bswap_type, NULL, "bswapdst");
       convert_stmt = gimple_build_assign (tgt, NOP_EXPR, tmp);
       gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT);
@@ -2498,7 +2497,7 @@ pass_optimize_bswap::execute (function *fun)
              /* Already in canonical form, nothing to do.  */
              if (code == LROTATE_EXPR || code == RROTATE_EXPR)
                continue;
-             load_type = uint16_type_node;
+             load_type = bswap_type = uint16_type_node;
              break;
            case 32:
              load_type = uint32_type_node;