re PR tree-optimization/38884 (missed FRE with __real and __imag)
authorRichard Guenther <rguenther@suse.de>
Thu, 6 Oct 2011 08:41:44 +0000 (08:41 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 6 Oct 2011 08:41:44 +0000 (08:41 +0000)
2011-10-06  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/38884
* tree-ssa-sccvn.c (vn_reference_lookup_3): Handle partial
reads from aggregate SSA names.

* gcc.dg/tree-ssa/ssa-fre-34.c: New testcase.
* gcc.dg/tree-ssa/ssa-fre-35.c: Likewise.

From-SVN: r179593

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 4e459f40a8ff67a97f080a419eb334443abd7c21..31b6af7e2287074751a74ed7142e8b1755aae564 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-06  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/38884
+       * tree-ssa-sccvn.c (vn_reference_lookup_3): Handle partial
+       reads from aggregate SSA names.
+
 2011-10-05  Jakub Jelinek  <jakub@redhat.com>
 
        * tree-vect-patterns.c (vect_pattern_recog_1): Add stmts_to_replace
index cbd8f7147bf46d0512984f73eabe0de64f0c8ed8..458bacb456c2cf1d9b20c639ef9d339e780c51eb 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-06  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/38884
+       * gcc.dg/tree-ssa/ssa-fre-34.c: New testcase.
+       * gcc.dg/tree-ssa/ssa-fre-35.c: Likewise.
+
 2011-10-05  David S. Miller  <davem@davemloft.net>
 
        * gcc.target/sparc/lzd.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c
new file mode 100644 (file)
index 0000000..b0b54a2
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
+
+#define vector __attribute__((vector_size(16) ))
+
+struct {
+    float i;
+    vector float global_res;
+} s;
+float foo(float f)
+{
+  vector float res = (vector float){0.0f,f,0.0f,1.0f};
+  s.global_res = res;
+  return *((float*)&s.global_res + 1);
+}
+
+/* { dg-final { scan-tree-dump "Replaced BIT_FIELD_REF.*with f" "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c
new file mode 100644 (file)
index 0000000..dfbd7c1
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
+
+struct s { _Complex float i; };
+void g(struct s *);
+
+float a1 (float dd)
+{
+  struct s sv;
+  sv.i = dd;
+  float d = __real__ sv.i;
+  g(&sv);
+  return d;
+}
+
+/* { dg-final { scan-tree-dump "Replaced REALPART_EXPR.*with dd" "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */
index 3b1ad3da269f918ccac73f3c3907714f143e17bd..c33b87dd7fe29e9d5053e318b510ad13fc7230bc 100644 (file)
@@ -1489,7 +1489,66 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
        }
     }
 
-  /* 4) For aggregate copies translate the reference through them if
+  /* 4) Assignment from an SSA name which definition we may be able
+     to access pieces from.  */
+  else if (ref->size == maxsize
+          && is_gimple_reg_type (vr->type)
+          && gimple_assign_single_p (def_stmt)
+          && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
+    {
+      tree rhs1 = gimple_assign_rhs1 (def_stmt);
+      gimple def_stmt2 = SSA_NAME_DEF_STMT (rhs1);
+      if (is_gimple_assign (def_stmt2)
+         && (gimple_assign_rhs_code (def_stmt2) == COMPLEX_EXPR
+             || gimple_assign_rhs_code (def_stmt2) == CONSTRUCTOR)
+         && types_compatible_p (vr->type, TREE_TYPE (TREE_TYPE (rhs1))))
+       {
+         tree base2;
+         HOST_WIDE_INT offset2, size2, maxsize2, off;
+         base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
+                                          &offset2, &size2, &maxsize2);
+         off = offset - offset2;
+         if (maxsize2 != -1
+             && maxsize2 == size2
+             && operand_equal_p (base, base2, 0)
+             && offset2 <= offset
+             && offset2 + size2 >= offset + maxsize)
+           {
+             tree val = NULL_TREE;
+             HOST_WIDE_INT elsz
+               = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (TREE_TYPE (rhs1))));
+             if (gimple_assign_rhs_code (def_stmt2) == COMPLEX_EXPR)
+               {
+                 if (off == 0)
+                   val = gimple_assign_rhs1 (def_stmt2);
+                 else if (off == elsz)
+                   val = gimple_assign_rhs2 (def_stmt2);
+               }
+             else if (gimple_assign_rhs_code (def_stmt2) == CONSTRUCTOR
+                      && off % elsz == 0)
+               {
+                 tree ctor = gimple_assign_rhs1 (def_stmt2);
+                 unsigned i = off / elsz;
+                 if (i < CONSTRUCTOR_NELTS (ctor))
+                   {
+                     constructor_elt *elt = CONSTRUCTOR_ELT (ctor, i);
+                     if (compare_tree_int (elt->index, i) == 0)
+                       val = elt->value;
+                   }
+               }
+             if (val)
+               {
+                 unsigned int value_id = get_or_alloc_constant_value_id (val);
+                 return vn_reference_insert_pieces
+                          (vuse, vr->set, vr->type,
+                           VEC_copy (vn_reference_op_s, heap, vr->operands),
+                           val, value_id);
+               }
+           }
+       }
+    }
+
+  /* 5) For aggregate copies translate the reference through them if
      the copy kills ref.  */
   else if (vn_walk_kind == VN_WALKREWRITE
           && gimple_assign_single_p (def_stmt)
@@ -1587,7 +1646,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
       return NULL;
     }
 
-  /* 5) For memcpy copies translate the reference through them if
+  /* 6) For memcpy copies translate the reference through them if
      the copy kills ref.  */
   else if (vn_walk_kind == VN_WALKREWRITE
           && is_gimple_reg_type (vr->type)