re PR tree-optimization/39362 (ICE failing to coalesce ab SSA names)

2009-03-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/39362
	* tree-ssa-sccvn.c (visit_use): Stores and copies from SSA_NAMEs
	that occur in abnormal PHIs should be varying.

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

From-SVN: r144626
This commit is contained in:
Richard Guenther 2009-03-04 23:00:25 +00:00 committed by Richard Biener
parent b78ef3ee22
commit b505e785a3
4 changed files with 129 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2009-03-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/39362
* tree-ssa-sccvn.c (visit_use): Stores and copies from SSA_NAMEs
that occur in abnormal PHIs should be varying.
2009-03-04 Zdenek Dvorak <ook@ucw.cz>
* tree-scalar-evolution.c (analyze_scalar_evolution_in_loop):

View File

@ -1,3 +1,8 @@
2009-03-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/39362
* g++.dg/torture/pr39362.C: New testcase.
2009-03-04 Jason Merrill <jason@redhat.com>
Giovanni Bajo <giovannibajo@gcc.gnu.org>

View File

@ -0,0 +1,105 @@
/* { dg-do compile } */
void *fastMalloc (int n);
void fastFree (void *p);
template <class T> struct C
{
void deref () { delete static_cast <T *>(this); }
};
template <typename T>
struct D
{
D (T *ptr) : m_ptr (ptr) { }
~D () { if (T * ptr = m_ptr) ptr->deref (); }
T *operator-> () const;
T *m_ptr;
typedef T *UnspecifiedBoolType;
operator UnspecifiedBoolType () const;
};
template <typename T> struct E
{
static void destruct (T * begin, T * end)
{
for (T * cur = begin; cur != end; ++cur)
cur->~T ();
}
};
template <typename T> class F;
template <typename T> struct G
{
static void destruct (T * begin, T * end)
{
E <T>::destruct (begin, end);
}
static void uninitializedFill (T * dst, T * dstEnd, const T & val)
{
F<T>::uninitializedFill (dst, dstEnd, val);
}
};
template <typename T> struct H
{
void allocateBuffer (int newCapacity)
{
m_buffer = static_cast <T *>(fastMalloc (newCapacity * sizeof (T)));
}
void deallocateBuffer (T * bufferToDeallocate)
{
if (m_buffer == bufferToDeallocate)
fastFree (bufferToDeallocate);
}
T *buffer () { }
int capacity () const { }
T *m_buffer;
};
template <typename T, int cap> class I;
template <typename T> struct I <T, 0> : H <T>
{
I (int capacity) { allocateBuffer (capacity); }
~I () { deallocateBuffer (buffer ()); }
using H <T>::allocateBuffer;
H <T>::buffer;
};
template <typename T, int cap = 0> struct J
{
typedef T *iterator;
~J () { if (m_size) shrink (0); }
J (const J &);
int capacity () const { m_buffer.capacity (); }
T & operator[](int i) { }
iterator begin () { }
iterator end () { return begin () + m_size; }
void shrink (int size);
template <typename U> void append (const U &);
int m_size;
I <T, cap> m_buffer;
};
template <typename T, int cap>
J <T, cap>::J (const J & other) : m_buffer (other.capacity ())
{
}
template <typename T, int cap>
void J <T, cap>::shrink (int size)
{
G <T>::destruct (begin () + size, end ());
m_size = size;
}
struct A : public C <A>
{
virtual ~A ();
typedef J <D <A> > B;
virtual A *firstChild () const;
virtual A *nextSibling () const;
virtual const B & children (int length);
B m_children;
};
const A::B &
A::children (int length)
{
for (D <A> obj = firstChild (); obj; obj = obj->nextSibling ())
{
B children = obj->children (2);
for (unsigned i = 0; i <length; ++i)
m_children.append (children[i]);
}
}

View File

@ -2367,14 +2367,19 @@ visit_use (tree use)
VN_INFO (lhs)->expr = NULL_TREE;
}
if (TREE_CODE (lhs) == SSA_NAME
/* We can substitute SSA_NAMEs that are live over
abnormal edges with their constant value. */
&& !(gimple_assign_copy_p (stmt)
&& is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
&& !(simplified
&& is_gimple_min_invariant (simplified))
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
if ((TREE_CODE (lhs) == SSA_NAME
/* We can substitute SSA_NAMEs that are live over
abnormal edges with their constant value. */
&& !(gimple_assign_copy_p (stmt)
&& is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
&& !(simplified
&& is_gimple_min_invariant (simplified))
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
/* Stores or copies from SSA_NAMEs that are live over
abnormal edges are a problem. */
|| (gimple_assign_single_p (stmt)
&& TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt))))
changed = defs_to_varying (stmt);
else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs))
{