re PR tree-optimization/38885 (missed FRE with BIT_FIELD_REF and vectors)
authorRichard Guenther <rguenther@suse.de>
Wed, 5 Oct 2011 14:35:15 +0000 (14:35 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 5 Oct 2011 14:35:15 +0000 (14:35 +0000)
2011-10-05  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/38885
* tree-ssa-sccvn.c (vn_reference_lookup_3): Handle partial reads
from constants.

* gcc.dg/tree-ssa/ssa-fre-33.c: New testcase.

From-SVN: r179556

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

index 3891393d604dcdedd0871a30c28a01e2408b05e5..e6bf96d9c92fe18d96ca79b9ec74bd8df4aef26d 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-05  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/38885
+       * tree-ssa-sccvn.c (vn_reference_lookup_3): Handle partial reads
+       from constants.
+
 2011-10-05  Bernd Schmidt  <bernds@codesourcery.com>
 
        * doc/invoke.texi (-fshrink-wrap): Document.
index 6ddbccda88a03d456e8dad0b1049c6b2458a73fb..4a09d43266d8b245438e709ddabbfcd6f4559e91 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-05  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/38885
+       * gcc.dg/tree-ssa/ssa-fre-33.c: New testcase.
+
 2011-10-05  Bernd Schmidt  <bernds@codesourcery.com>
 
        * gcc.target/i386/sw-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-33.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-33.c
new file mode 100644 (file)
index 0000000..daba77d
--- /dev/null
@@ -0,0 +1,21 @@
+/* { 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 x;
+int main(int argc)
+{
+  vector float res = (vector float){0.0f,0.0f,0.0f,1.0f};
+  res += (vector float){1.0f,2.0f,3.0f,4.0f};
+  s.global_res = res;
+  x = *((float*)&s.global_res + 1);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "Replaced BIT_FIELD_REF.*with 2" "fre1" } } */
+/* { dg-final { cleanup-tree-dump "fre1" } } */
index 4b5d388cf31c647ea64d1a53c5aaed08c95341a8..3b1ad3da269f918ccac73f3c3907714f143e17bd 100644 (file)
@@ -1442,7 +1442,54 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
        }
     }
 
-  /* 3) For aggregate copies translate the reference through them if
+  /* 3) Assignment from a constant.  We can use folds native encode/interpret
+     routines to extract the assigned bits.  */
+  else if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
+          && ref->size == maxsize
+          && maxsize % BITS_PER_UNIT == 0
+          && offset % BITS_PER_UNIT == 0
+          && is_gimple_reg_type (vr->type)
+          && gimple_assign_single_p (def_stmt)
+          && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
+    {
+      tree base2;
+      HOST_WIDE_INT offset2, size2, maxsize2;
+      base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
+                                      &offset2, &size2, &maxsize2);
+      if (maxsize2 != -1
+         && maxsize2 == size2
+         && size2 % BITS_PER_UNIT == 0
+         && offset2 % BITS_PER_UNIT == 0
+         && operand_equal_p (base, base2, 0)
+         && offset2 <= offset
+         && offset2 + size2 >= offset + maxsize)
+       {
+         /* We support up to 512-bit values (for V8DFmode).  */
+         unsigned char buffer[64];
+         int len;
+
+         len = native_encode_expr (gimple_assign_rhs1 (def_stmt),
+                                   buffer, sizeof (buffer));
+         if (len > 0)
+           {
+             tree val = native_interpret_expr (vr->type,
+                                               buffer
+                                               + ((offset - offset2)
+                                                  / BITS_PER_UNIT),
+                                               ref->size / BITS_PER_UNIT);
+             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);
+               }
+           }
+       }
+    }
+
+  /* 4) 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)
@@ -1540,7 +1587,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
       return NULL;
     }
 
-  /* 4) For memcpy copies translate the reference through them if
+  /* 5) 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)