re PR target/34641 (ICE in reload_cse_simplify_operands, at postreload.c:395)

2008-01-10  Andreas Krebbel  <krebbel1@de.ibm.com>

	PR middle-end/34641
	* reload.c (push_reload): Add assertions.  All constants from
	reg_equiv_constant should have been used for replacing the respective
	pseudo earlier.
	(find_reloads_address): Invoke find_reloads_address_part for
	constant taken from the reg_equiv_constant array.

2008-01-10  Andreas Krebbel  <krebbel1@de.ibm.com>

	PR middle-end/34641
	* g++.dg/torture/pr34641.C: New testcase.

From-SVN: r131445
This commit is contained in:
Andreas Krebbel 2008-01-10 16:46:26 +00:00 committed by Andreas Krebbel
parent 71ae85578b
commit 90d12f1f04
4 changed files with 211 additions and 21 deletions

View File

@ -1,3 +1,12 @@
2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com>
PR middle-end/34641
* reload.c (push_reload): Add assertions. All constants from
reg_equiv_constant should have been used for replacing the respective
pseudo earlier.
(find_reloads_address): Invoke find_reloads_address_part for
constant taken from the reg_equiv_constant array.
2008-01-10 Steven Bosscher <stevenb.gcc@gmail.com>
* tree-ssa-sccvn.h (struct vn_ssa_aux): Make the most accessed

View File

@ -922,29 +922,33 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
if (outmode == VOIDmode && out != 0)
outmode = GET_MODE (out);
/* If IN is a pseudo register everywhere-equivalent to a constant, and
it is not in a hard register, reload straight from the constant,
since we want to get rid of such pseudo registers.
Often this is done earlier, but not always in find_reloads_address. */
/* If find_reloads and friends until now missed to replace a pseudo
with a constant of reg_equiv_constant something went wrong
beforehand.
Note that it can't simply be done here if we missed it earlier
since the constant might need to be pushed into the literal pool
and the resulting memref would probably need further
reloading. */
if (in != 0 && REG_P (in))
{
int regno = REGNO (in);
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
&& reg_equiv_constant[regno] != 0)
in = reg_equiv_constant[regno];
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|| reg_renumber[regno] >= 0
|| reg_equiv_constant[regno] == NULL_RTX);
}
/* Likewise for OUT. Of course, OUT will never be equivalent to
an actual constant, but it might be equivalent to a memory location
(in the case of a parameter). */
/* reg_equiv_constant only contains constants which are obviously
not appropriate as destination. So if we would need to replace
the destination pseudo with a constant we are in real
trouble. */
if (out != 0 && REG_P (out))
{
int regno = REGNO (out);
if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
&& reg_equiv_constant[regno] != 0)
out = reg_equiv_constant[regno];
gcc_assert (regno < FIRST_PSEUDO_REGISTER
|| reg_renumber[regno] >= 0
|| reg_equiv_constant[regno] == NULL_RTX);
}
/* If we have a read-write operand with an address side-effect,
@ -4772,15 +4776,12 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
{
regno = REGNO (ad);
/* If the register is equivalent to an invariant expression, substitute
the invariant, and eliminate any eliminable register references. */
tem = reg_equiv_constant[regno];
if (tem != 0
&& (tem = eliminate_regs (tem, mode, insn))
&& strict_memory_address_p (mode, tem))
if (reg_equiv_constant[regno] != 0)
{
*loc = ad = tem;
return 0;
find_reloads_address_part (reg_equiv_constant[regno], loc,
base_reg_class (mode, MEM, SCRATCH),
GET_MODE (ad), opnum, type, ind_levels);
return 1;
}
tem = reg_equiv_memory_loc[regno];

View File

@ -1,3 +1,8 @@
2008-01-10 Andreas Krebbel <krebbel1@de.ibm.com>
PR middle-end/34641
* g++.dg/torture/pr34641.C: New testcase.
2008-01-10 Richard Guenther <rguenther@suse.de>
PR tree-optimization/34651

View File

@ -0,0 +1,175 @@
// { dg-require-effective-target fpic }
// { dg-options "-fPIC" }
// { dg-do compile }
typedef long unsigned int size_t;
extern "C" void *
malloc (size_t __size)
throw () __attribute__ ((__malloc__));
namespace std __attribute__ ((__visibility__ ("default")))
{
using::size_t;
}
inline void *operator
new (std::size_t, void *__p)
throw ()
{
return __p;
}
template < class _T1, class _T2 > struct pair
{
_T1 first;
_T2 second;
pair (const _T1 & __a, const _T2 & __b):first (__a), second (__b)
{
}
template < class _U1, class _U2 >
pair (const pair < _U1, _U2 > &__p):first (__p.first), second (__p.second)
{
}
};
template < class _T1, class _T2 >
inline pair < _T1, _T2 > make_pair (_T1 __x, _T2 __y)
{
return pair < _T1, _T2 > (__x, __y);
}
template < typename _Tp > inline const _Tp &
max (const _Tp & __a, const _Tp & __b)
{
}
typedef unsigned short int uint16_t;
typedef unsigned long int uintptr_t;
typedef uint16_t UChar;
namespace std __attribute__ ((__visibility__ ("default")))
{
struct __numeric_limits_base
{
};
template < typename _Tp > struct numeric_limits:public __numeric_limits_base
{
static _Tp max () throw ()
{
}
};
}
template < typename T > class VectorBufferBase
{
public:
void allocateBuffer (size_t newCapacity)
{
if (newCapacity > std::numeric_limits < size_t >::max () / sizeof (T))
*(int *) (uintptr_t) 0xbbadbeef = 0;
}
};
template < typename T, size_t inlineCapacity > class VectorBuffer;
template < typename T > class VectorBuffer < T, 0 >:private VectorBufferBase <
T >
{
typedef VectorBufferBase < T > Base;
using Base::allocateBuffer;
};
template < typename T, size_t inlineCapacity = 0 > class Vector
{
typedef VectorBuffer < T, inlineCapacity > Impl;
public:
typedef T *iterator;
size_t size () const
{
return m_size;
}
size_t capacity () const
{
}
iterator begin ()
{
}
iterator end ()
{
return begin () + m_size;
}
void shrink (size_t size);
void reserveCapacity (size_t newCapacity);
void clear ()
{
shrink (0);
}
template < typename U > void append (const U &);
void expandCapacity (size_t newMinCapacity);
template < typename U > U * expandCapacity (size_t newMinCapacity, U *);
size_t m_size;
Impl m_impl;
};
template < typename T, size_t inlineCapacity >
void Vector < T, inlineCapacity >::expandCapacity (size_t newMinCapacity)
{
reserveCapacity (max
(newMinCapacity,
max (static_cast < size_t > (16),
capacity () + capacity () / 4 + 1)));
}
template < typename T, size_t inlineCapacity >
template < typename U >
inline U * Vector < T,
inlineCapacity >::expandCapacity (size_t newMinCapacity, U * ptr)
{
expandCapacity (newMinCapacity);
}
template < typename T, size_t inlineCapacity >
void Vector < T, inlineCapacity >::reserveCapacity (size_t newCapacity)
{
m_impl.allocateBuffer (newCapacity);
}
template < typename T, size_t inlineCapacity >
template < typename U >
inline void Vector < T, inlineCapacity >::append (const U & val)
{
const U *ptr = &val;
if (size () == capacity ())
ptr = expandCapacity (size () + 1, ptr);
new (end ())T (*ptr);
}
class Range;
class TextIterator
{
public:
explicit TextIterator (const Range *,
bool emitCharactersBetweenAllVisiblePositions =
false);
bool atEnd () const
{
}
void advance ();
int length () const
{
}
};
UChar *
plainTextToMallocAllocatedBuffer (const Range * r, unsigned &bufferLength)
{
static const unsigned cMaxSegmentSize = 1 << 16;
typedef pair < UChar *, unsigned >TextSegment;
Vector < TextSegment > *textSegments = 0;
Vector < UChar > textBuffer;
for (TextIterator it (r); !it.atEnd (); it.advance ())
{
if (textBuffer.size ()
&& textBuffer.size () + it.length () > cMaxSegmentSize)
{
UChar *newSegmentBuffer =
static_cast <
UChar * >(malloc (textBuffer.size () * sizeof (UChar)));
if (!textSegments)
textSegments = new Vector < TextSegment >;
textSegments->
append (make_pair (newSegmentBuffer, textBuffer.size ()));
textBuffer.clear ();
}
}
}