re PR tree-optimization/49770 (wrong code with -fno-tree-forwprop)

2011-07-21  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/49770
	* tree-ssa-sccvn.c (valueize_refs_1): Return whether we
	valueized any operand.  Renamed from ...
	(valueize_refs): ... this.  New wrapper around valueize_refs_1.
	(valueize_shared_reference_ops_from_ref): Return whether we
	valueized any operand.
	(vn_reference_lookup): Only when we valueized any operand
	use the valueized reference for alias analysis.  Do not preserve
	the original reference tree in this case.

	* g++.dg/torture/pr49770.C: New testcase.

From-SVN: r176567
This commit is contained in:
Richard Guenther 2011-07-21 13:19:18 +00:00 committed by Richard Biener
parent a423549540
commit 3ceaf2f571
4 changed files with 150 additions and 14 deletions

View File

@ -1,3 +1,15 @@
2011-07-21 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49770
* tree-ssa-sccvn.c (valueize_refs_1): Return whether we
valueized any operand. Renamed from ...
(valueize_refs): ... this. New wrapper around valueize_refs_1.
(valueize_shared_reference_ops_from_ref): Return whether we
valueized any operand.
(vn_reference_lookup): Only when we valueized any operand
use the valueized reference for alias analysis. Do not preserve
the original reference tree in this case.
2011-07-21 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (ix86_decompose_address): Reject all but

View File

@ -1,3 +1,8 @@
2011-07-21 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49770
* g++.dg/torture/pr49770.C: New testcase.
2011-07-21 Kai Tietz <ktietz@redhat.com>
* gcc.dg/tree-ssa/pr30978.c: adjusted.

View File

@ -0,0 +1,86 @@
/* { dg-do run } */
/* { dg-options "-std=c++0x -fno-tree-forwprop" } */
typedef __SIZE_TYPE__ size_t;
template < typename > struct remove_reference;
template < typename _Tp > struct remove_reference <_Tp & >
{
typedef _Tp type;
};
template < typename _Tp > typename remove_reference < _Tp >::type &&
move (_Tp && __t)
{
return static_cast < typename remove_reference < _Tp >::type && >(__t);
}
template < typename _Tp > void
stdswap (_Tp & __a, _Tp & __b)
{
_Tp __tmp (__a);
__a = (__b);
__b = (__tmp);
}
struct _Deque_iterator
{
int *_M_cur;
int *_M_first;
int *_M_last;
int **_M_node;
};
static inline int operatorMIN (_Deque_iterator & __x, _Deque_iterator & __y)
{
return sizeof (int) * (__x._M_node - __y._M_node - 1)
+ (__x._M_cur - __x._M_first) + (__y._M_last - __y._M_cur);
}
struct deque
{
deque & operator = (deque && __x)
{
stdswap (_M_finish, __x._M_finish);
return *this;
}
size_t size ()
{
return operatorMIN (_M_finish, _M_start);
}
deque ():
_M_map (), _M_map_size (), _M_start (), _M_finish ()
{
_M_start._M_last = _M_start._M_first + sizeof (int);
}
int **_M_map;
size_t _M_map_size;
_Deque_iterator _M_start;
_Deque_iterator _M_finish;
};
struct queue
{
deque c;
size_t size ()
{
return c.size ();
}
};
void
test01 ()
{
queue a, b;
++a.c._M_finish._M_cur;
b = move (a);
if (!b.size ())
__builtin_abort ();
}
main ()
{
test01 ();
}

View File

@ -1146,29 +1146,51 @@ fully_constant_vn_reference_p (vn_reference_t ref)
/* Transform any SSA_NAME's in a vector of vn_reference_op_s
structures into their value numbers. This is done in-place, and
the vector passed in is returned. */
the vector passed in is returned. *VALUEIZED_ANYTHING will specify
whether any operands were valueized. */
static VEC (vn_reference_op_s, heap) *
valueize_refs (VEC (vn_reference_op_s, heap) *orig)
valueize_refs_1 (VEC (vn_reference_op_s, heap) *orig, bool *valueized_anything)
{
vn_reference_op_t vro;
unsigned int i;
*valueized_anything = false;
FOR_EACH_VEC_ELT (vn_reference_op_s, orig, i, vro)
{
if (vro->opcode == SSA_NAME
|| (vro->op0 && TREE_CODE (vro->op0) == SSA_NAME))
{
vro->op0 = SSA_VAL (vro->op0);
tree tem = SSA_VAL (vro->op0);
if (tem != vro->op0)
{
*valueized_anything = true;
vro->op0 = tem;
}
/* If it transforms from an SSA_NAME to a constant, update
the opcode. */
if (TREE_CODE (vro->op0) != SSA_NAME && vro->opcode == SSA_NAME)
vro->opcode = TREE_CODE (vro->op0);
}
if (vro->op1 && TREE_CODE (vro->op1) == SSA_NAME)
vro->op1 = SSA_VAL (vro->op1);
{
tree tem = SSA_VAL (vro->op1);
if (tem != vro->op1)
{
*valueized_anything = true;
vro->op1 = tem;
}
}
if (vro->op2 && TREE_CODE (vro->op2) == SSA_NAME)
vro->op2 = SSA_VAL (vro->op2);
{
tree tem = SSA_VAL (vro->op2);
if (tem != vro->op2)
{
*valueized_anything = true;
vro->op2 = tem;
}
}
/* If it transforms from an SSA_NAME to an address, fold with
a preceding indirect reference. */
if (i > 0
@ -1203,20 +1225,29 @@ valueize_refs (VEC (vn_reference_op_s, heap) *orig)
return orig;
}
static VEC (vn_reference_op_s, heap) *
valueize_refs (VEC (vn_reference_op_s, heap) *orig)
{
bool tem;
return valueize_refs_1 (orig, &tem);
}
static VEC(vn_reference_op_s, heap) *shared_lookup_references;
/* Create a vector of vn_reference_op_s structures from REF, a
REFERENCE_CLASS_P tree. The vector is shared among all callers of
this function. */
this function. *VALUEIZED_ANYTHING will specify whether any
operands were valueized. */
static VEC(vn_reference_op_s, heap) *
valueize_shared_reference_ops_from_ref (tree ref)
valueize_shared_reference_ops_from_ref (tree ref, bool *valueized_anything)
{
if (!ref)
return NULL;
VEC_truncate (vn_reference_op_s, shared_lookup_references, 0);
copy_reference_ops_from_ref (ref, &shared_lookup_references);
shared_lookup_references = valueize_refs (shared_lookup_references);
shared_lookup_references = valueize_refs_1 (shared_lookup_references,
valueized_anything);
return shared_lookup_references;
}
@ -1694,12 +1725,14 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
VEC (vn_reference_op_s, heap) *operands;
struct vn_reference_s vr1;
tree cst;
bool valuezied_anything;
if (vnresult)
*vnresult = NULL;
vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
vr1.operands = operands = valueize_shared_reference_ops_from_ref (op);
vr1.operands = operands
= valueize_shared_reference_ops_from_ref (op, &valuezied_anything);
vr1.type = TREE_TYPE (op);
vr1.set = get_alias_set (op);
vr1.hashcode = vn_reference_compute_hash (&vr1);
@ -1711,12 +1744,12 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
{
vn_reference_t wvnresult;
ao_ref r;
/* Make sure to use a valueized reference ... */
if (!ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type, vr1.operands))
/* Make sure to use a valueized reference if we valueized anything.
Otherwise preserve the full reference for advanced TBAA. */
if (!valuezied_anything
|| !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type,
vr1.operands))
ao_ref_init (&r, op);
else
/* ... but also preserve a full reference tree for advanced TBAA. */
r.ref = op;
vn_walk_kind = kind;
wvnresult =
(vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,