re PR tree-optimization/38884 (missed FRE with __real and __imag)

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
This commit is contained in:
Richard Guenther 2011-10-06 08:41:44 +00:00 committed by Richard Biener
parent d1fc143dd6
commit 0147184e2b
5 changed files with 108 additions and 2 deletions

View 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

View 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.

View file

@ -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" } } */

View file

@ -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" } } */

View 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)