re PR rtl-optimization/48037 (Missed optimization: unnecessary register moves)
authorRichard Guenther <rguenther@suse.de>
Tue, 15 Mar 2011 12:22:12 +0000 (12:22 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 15 Mar 2011 12:22:12 +0000 (12:22 +0000)
2011-03-15  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/48037
* tree-ssa.c (maybe_rewrite_mem_ref_base): Rewrite vector
selects into BIT_FIELD_REFs.
(non_rewritable_mem_ref_base): Check if a MEM_REF is a
vector select.

* gcc.target/i386/pr48037-1.c: New testcase.

From-SVN: r170986

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr48037-1.c [new file with mode: 0644]
gcc/tree-ssa.c

index ec59459bc97dd6c0fc64ad5f7c93e53573e6cf50..198b1b79de2c3fcac656ac12c6c7fb2dff0b7a0f 100644 (file)
@@ -1,3 +1,11 @@
+2011-03-15  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/48037
+       * tree-ssa.c (maybe_rewrite_mem_ref_base): Rewrite vector
+       selects into BIT_FIELD_REFs.
+       (non_rewritable_mem_ref_base): Check if a MEM_REF is a
+       vector select.
+
 2011-03-15  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/48129
index 2db72ee2a5d50faa1ff39e39b72cc5bea6e4de15..6c209b0b354f8050a21c5b3ee0166d46f77c0272 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-15  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/48037
+       * gcc.target/i386/pr48037-1.c: New testcase.
+
 2011-03-15  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/41490
diff --git a/gcc/testsuite/gcc.target/i386/pr48037-1.c b/gcc/testsuite/gcc.target/i386/pr48037-1.c
new file mode 100644 (file)
index 0000000..30c81e7
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O -fno-math-errno" } */
+
+typedef double __m128d __attribute__((vector_size(16)));
+__m128d vsqrt1 (__m128d const x)
+{
+  double const* __restrict__ const y = (double const*)&x;
+  double const a = __builtin_sqrt(y[0]);
+  double const b = __builtin_sqrt(y[1]);
+  return (__m128d) { a, b };
+}
+
+/* Verify we do not spill x to the stack.  */
+/* { dg-final { scan-assembler-not "%rsp" } } */
index 5c9e0d88bf2ed0ef33f25c2d072572313ff3d9b1..f28e5d15c72d2f5ebc810a822b57ba6342a29a97 100644 (file)
@@ -1838,18 +1838,32 @@ maybe_rewrite_mem_ref_base (tree *tp)
     tp = &TREE_OPERAND (*tp, 0);
   if (TREE_CODE (*tp) == MEM_REF
       && TREE_CODE (TREE_OPERAND (*tp, 0)) == ADDR_EXPR
-      && integer_zerop (TREE_OPERAND (*tp, 1))
       && (sym = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0))
       && DECL_P (sym)
       && !TREE_ADDRESSABLE (sym)
       && symbol_marked_for_renaming (sym))
     {
-      if (!useless_type_conversion_p (TREE_TYPE (*tp),
-                                     TREE_TYPE (sym)))
-       *tp = build1 (VIEW_CONVERT_EXPR,
-                       TREE_TYPE (*tp), sym);
-      else
-       *tp = sym;
+      if (TREE_CODE (TREE_TYPE (sym)) == VECTOR_TYPE
+         && useless_type_conversion_p (TREE_TYPE (*tp),
+                                       TREE_TYPE (TREE_TYPE (sym)))
+         && multiple_of_p (sizetype, TREE_OPERAND (*tp, 1),
+                           TYPE_SIZE_UNIT (TREE_TYPE (*tp))))
+       {
+         *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym, 
+                       TYPE_SIZE (TREE_TYPE (*tp)),
+                       int_const_binop (MULT_EXPR,
+                                        bitsize_int (BITS_PER_UNIT),
+                                        TREE_OPERAND (*tp, 1), 0));
+       }
+      else if (integer_zerop (TREE_OPERAND (*tp, 1)))
+       {
+         if (!useless_type_conversion_p (TREE_TYPE (*tp),
+                                         TREE_TYPE (sym)))
+           *tp = build1 (VIEW_CONVERT_EXPR,
+                         TREE_TYPE (*tp), sym);
+         else
+           *tp = sym;
+       }
     }
 }
 
@@ -1869,11 +1883,18 @@ non_rewritable_mem_ref_base (tree ref)
     base = TREE_OPERAND (base, 0);
 
   /* But watch out for MEM_REFs we cannot lower to a
-     VIEW_CONVERT_EXPR.  */
+     VIEW_CONVERT_EXPR or a BIT_FIELD_REF.  */
   if (TREE_CODE (base) == MEM_REF
       && TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
     {
       tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
+      if (TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE
+         && useless_type_conversion_p (TREE_TYPE (base),
+                                       TREE_TYPE (TREE_TYPE (decl)))
+         && double_int_fits_in_uhwi_p (mem_ref_offset (base))
+         && multiple_of_p (sizetype, TREE_OPERAND (base, 1),
+                           TYPE_SIZE_UNIT (TREE_TYPE (base))))
+       return NULL_TREE;
       if (DECL_P (decl)
          && (!integer_zerop (TREE_OPERAND (base, 1))
              || (DECL_SIZE (decl)