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:
parent
b78ef3ee22
commit
b505e785a3
@ -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):
|
||||
|
@ -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>
|
||||
|
||||
|
105
gcc/testsuite/g++.dg/torture/pr39362.C
Normal file
105
gcc/testsuite/g++.dg/torture/pr39362.C
Normal 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]);
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user