Commit 6c3cb698 by Kirill Yukhin Committed by H.J. Lu

re PR middle-end/49519 (Revision 175272 miscompiled 447.dealII in SPEC CPU 2006)

Fix PR middle-end/49519.

gcc/

2011-07-08  Kirill Yukhin  <kirill.yukhin@intel.com>

	PR middle-end/49519
	* calls.c (mem_overlaps_already_clobbered_arg_p): Additional
	check if address is stored in register. If so - give up.
	(check_sibcall_argument_overlap_1): Do not perform check of
	overlapping when it is call to address.

gcc/tessuite/

2011-07-08  Kirill Yukhin  <kirill.yukhin@intel.com>

	PR middle-end/49519
	* g++.dg/torture/pr49519.C: New test.

From-SVN: r176042
parent 7d8d6d73
2011-07-08 Kirill Yukhin <kirill.yukhin@intel.com>
PR middle-end/49519
* calls.c (mem_overlaps_already_clobbered_arg_p): Additional
check if address is stored in register. If so - give up.
(check_sibcall_argument_overlap_1): Do not perform check of
overlapping when it is call to address.
2011-07-08 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr.c (output_reload_insisf): Use 'REG_Z+1' instead
......
......@@ -1591,6 +1591,10 @@ mem_overlaps_already_clobbered_arg_p (rtx addr, unsigned HOST_WIDE_INT size)
&& (XEXP (addr, 0) == crtl->args.internal_arg_pointer
|| XEXP (addr, 1) == crtl->args.internal_arg_pointer))
return true;
/* If the address comes in a register, we have no idea of its origin so
give up and conservatively return true. */
else if (REG_P(addr))
return true;
else
return false;
......@@ -1831,6 +1835,10 @@ check_sibcall_argument_overlap_1 (rtx x)
code = GET_CODE (x);
/* We need not check the operands of the CALL expression itself. */
if (code == CALL)
return 0;
if (code == MEM)
return mem_overlaps_already_clobbered_arg_p (XEXP (x, 0),
GET_MODE_SIZE (GET_MODE (x)));
......
2011-07-08 Kirill Yukhin <kirill.yukhin@intel.com>
PR middle-end/49519
* g++.dg/torture/pr49519.C: New test.
2011-07-08 Martin Jambor <mjambor@suse.cz>
* gcc.dg/tree-ssa/sra-12.c: Skip dump scan on avr targets.
......
/* { dg-do run } */
#include <stdlib.h>
struct null_type {};
inline const null_type cnull() { return null_type(); }
template <class TT> struct cons;
class tuple;
template< int N >
struct get_class {
template<class TT >
inline static int& get(cons<TT>& t)
{
return get_class<N-1>::template get(t.tail);
}
};
template<>
struct get_class<0> {
template<class TT>
inline static int& get(cons<TT>& t)
{
return t.head;
}
};
template<int N, class T>
struct element
{
private:
typedef typename T::tail_type Next;
public:
typedef typename element<N-1, Next>::type type;
};
template<class T>
struct element<0,T>
{
typedef int type;
};
template<int N, class TT>
inline int& get(cons<TT>& c) {
return get_class<N>::template get(c);
}
template <class TT>
struct cons {
typedef TT tail_type;
int head;
tail_type tail;
cons() : head(), tail() {}
template <class T1, class T2, class T3, class T4>
cons( T1& t1, T2& t2, T3& t3, T4& t4 )
: head (t1),
tail (t2, t3, t4, cnull())
{}
};
template <>
struct cons<null_type> {
typedef null_type tail_type;
int head;
cons() : head() {}
template<class T1>
cons(T1& t1, const null_type&, const null_type&, const null_type&)
: head (t1) {}
};
template <class T0, class T1, class T2, class T3>
struct map_tuple_to_cons
{
typedef cons<typename map_tuple_to_cons<T1, T2, T3, null_type>::type> type;
};
template <>
struct map_tuple_to_cons<null_type, null_type, null_type, null_type>
{
typedef null_type type;
};
class tuple :
public map_tuple_to_cons<int, int, int, int>::type
{
public:
typedef typename
map_tuple_to_cons<int, int, int, int>::type inherited;
tuple(const int &t0,
const int &t1,
const int &t2,
const int &t3)
: inherited(t0, t1, t2, t3) {}
};
void foo(void (*boo)(int, int, int, int), tuple t)
{
boo(get<0>(t), get<1>(t), get<2>(t), get<3>(t));
}
int tailcalled_t1;
int tailcalled_t2;
int tailcalled_t3;
int tailcalled_t4;
void print(int t1, int t2, int t3, int t4)
{
tailcalled_t1 = t1;
tailcalled_t2 = t2;
tailcalled_t3 = t3;
tailcalled_t4 = t4;
}
int main ()
{
tuple t(1,2,3,4);
foo(print, t);
if( (get<0>(t) != tailcalled_t1)
||(get<1>(t) != tailcalled_t2)
||(get<2>(t) != tailcalled_t3)
||(get<3>(t) != tailcalled_t4))
abort();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment