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:
parent
a423549540
commit
3ceaf2f571
4 changed files with 150 additions and 14 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
86
gcc/testsuite/g++.dg/torture/pr49770.C
Normal file
86
gcc/testsuite/g++.dg/torture/pr49770.C
Normal 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 ();
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue