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>
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/46724
* 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>
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,
gcc_assert (!ef);
ef = e;
}
gcc_assert (ef
&& single_pred_p (ef->dest)
&& !phi_nodes (ef->dest)
&& ef->dest != EXIT_BLOCK_PTR);
gsi_insert_on_edge_immediate (ef, note);
/* If there are other predecessors to ef->dest, then
there must be PHI nodes for the modified
variable, and therefore there will be debug bind
stmts after the PHI nodes. The debug bind notes
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
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