Commit 23d5ed5d by Alexandre Oliva Committed by Alexandre Oliva

re PR debug/46240 (ice in maybe_register_def)

gcc/ChangeLog:
PR debug/46240
* tree-into-ssa.c (maybe_register_def): Do not attempt to add
debug bind stmt on merge edges.
gcc/testsuite/ChangeLog:
PR debug/46240
* g++.dg/debug/pr46240.cc: New.

From-SVN: r169035
parent 37d6a488
2011-01-19 Alexandre Oliva <aoliva@redhat.com> 2011-01-19 Alexandre Oliva <aoliva@redhat.com>
PR debug/46240
* tree-into-ssa.c (maybe_register_def): Do not attempt to add
debug bind stmt on merge edges.
2011-01-19 Alexandre Oliva <aoliva@redhat.com>
PR debug/47079 PR debug/47079
PR debug/46724 PR debug/46724
* function.c (instantiate_expr): Instantiate incoming rtl of * function.c (instantiate_expr): Instantiate incoming rtl of
......
2011-01-19 Alexandre Oliva <aoliva@redhat.com>
PR debug/46240
* g++.dg/debug/pr46240.cc: New.
2011-01-19 Jakub Jelinek <jakub@redhat.com> 2011-01-19 Jakub Jelinek <jakub@redhat.com>
PR c++/47303 PR c++/47303
......
// { dg-do compile }
// { dg-options "-O3 -g" }
template <typename T>
T &max (T &a, T &b)
{
if (a < b) return b; else return a;
}
int foo (double);
struct S
{
struct T
{
int dims, count;
T (int, int) : dims (), count () {}
};
T *rep;
S () {}
S (int r, int c) : rep (new T (r, c)) {}
~S () { delete rep; }
};
template <typename T>
struct U
{
static T epsilon () throw ();
};
template <class T>
struct V
{
struct W
{
T * data;
int count;
W (int n) : data (new T[n]), count () {}
};
V::W *rep;
S dimensions;
int slice_len;
V (S s) : rep (new V <T>::W (get_size (s))) {}
int capacity () { return slice_len; }
int get_size (S);
};
template <class T>
struct Z : public V <T>
{
Z () : V <T> (S (0, 0)) {}
Z (int r, int c) : V <T> (S (r, c)) {}
};
template <class T>
struct A : public Z <T>
{
A () : Z <T> () {}
A (int n, int m) : Z <T> (n, m) {}
};
template <class T>
struct B : public V <T>
{
};
struct C : public A <double>
{
C () : A <double> () {}
C (int r, int c) : A <double> (r, c) {}
};
struct D : public B <double>
{
};
template <class T>
struct E
{
};
template <class T>
struct G : public E <T>
{
};
struct H : public G <double>
{
};
template <class R>
struct I
{
R scl, sum;
void accum (R val)
{
R t = __builtin_fabs (val);
if (scl == t)
sum += 1;
}
operator R () { __builtin_sqrt (sum); return R (); }
};
template <class R>
struct J
{
template < class U > void accum (U val) {}
operator R () { return R (); }
};
template <class R>
struct K
{
R max;
template <class U> void accum (U val)
{
double z = __builtin_fabs (val);
max = ::max (max, z);
}
operator R () { return max; }
};
template <class R>
struct L
{
unsigned num;
template <class U> void accum (U) {}
operator R () { return num; }
};
template <class T, class R, class S>
void bar (V <T> &v, R &res, S acc)
{
for (int i = 0; i < v.capacity (); i++)
acc.accum ((i));
res = acc;
}
template <class T, class R>
void bar (B <T> &v, R)
{
R res;
bar (v, res, I <R> ());
}
template <class T, class R>
R bar (A <T> &v, R p)
{
R res;
if (p == 2)
bar (v, res, I <R> ());
else if (p == 1)
bar (v, res, J <R> ());
else if (p == sizeof (float) ? (p) : foo (p))
{
if (p > 0)
bar (v, res, K <R> ());
}
else if (p == 0)
bar (v, res, L <R> ());
return res;
}
template <class CT, class VectorT, class R>
void
baz (CT m, R p, R tol, int maxiter, VectorT)
{
VectorT y (0, 0), z (0, 1);
R q = 0;
R gamma = 0, gamma1 = 0;
gamma = bar (y, p);
(void) (bar (z, q) <= (gamma1 <= gamma));
}
int a = 100;
template <class CT, class VectorT, class R>
void
test (CT m, R p, VectorT)
{
VectorT x;
R sqrteps (U <R>::epsilon ());
baz (m, p, sqrteps, a, x);
}
void
fn (D x, double p)
{
bar (x, p);
}
void
fn (H x, double p)
{
test (x, p, C ());
}
...@@ -1869,11 +1869,27 @@ maybe_register_def (def_operand_p def_p, gimple stmt, ...@@ -1869,11 +1869,27 @@ maybe_register_def (def_operand_p def_p, gimple stmt,
gcc_assert (!ef); gcc_assert (!ef);
ef = e; ef = e;
} }
gcc_assert (ef /* If there are other predecessors to ef->dest, then
&& single_pred_p (ef->dest) there must be PHI nodes for the modified
&& !phi_nodes (ef->dest) variable, and therefore there will be debug bind
&& ef->dest != EXIT_BLOCK_PTR); stmts after the PHI nodes. The debug bind notes
gsi_insert_on_edge_immediate (ef, note); we'd insert would force the creation of a new
block (diverging codegen) and be redundant with
the post-PHI bind stmts, so don't add them.
As for the exit edge, there wouldn't be redundant
bind stmts, but there wouldn't be a PC to bind
them to either, so avoid diverging the CFG. */
if (ef && single_pred_p (ef->dest)
&& ef->dest != EXIT_BLOCK_PTR)
{
/* If there were PHI nodes in the node, we'd
have to make sure the value we're binding
doesn't need rewriting. But there shouldn't
be PHI nodes in a single-predecessor block,
so we just add the note. */
gsi_insert_on_edge_immediate (ef, note);
}
} }
else else
gsi_insert_after (&gsi, note, GSI_SAME_STMT); gsi_insert_after (&gsi, note, GSI_SAME_STMT);
......
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