From a3bb56f01d7d44f2114770debac8e172b1872a07 Mon Sep 17 00:00:00 2001 From: rguenth Date: Thu, 6 Oct 2011 08:41:44 +0000 Subject: [PATCH] 2011-10-06 Richard Guenther 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179593 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 +++ gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c | 18 +++++++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c | 17 ++++++++ gcc/tree-ssa-sccvn.c | 63 +++++++++++++++++++++++++++++- 5 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4e459f4..31b6af7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-10-06 Richard Guenther + + PR tree-optimization/38884 + * tree-ssa-sccvn.c (vn_reference_lookup_3): Handle partial + reads from aggregate SSA names. + 2011-10-05 Jakub Jelinek * tree-vect-patterns.c (vect_pattern_recog_1): Add stmts_to_replace diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cbd8f71..458bacb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-10-06 Richard Guenther + + 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 * 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 index 0000000..b0b54a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-34.c @@ -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 index 0000000..dfbd7c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-35.c @@ -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" } } */ diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 3b1ad3d..c33b87d 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -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) -- 2.7.4