From: Alexandre Oliva Date: Wed, 19 Jan 2011 22:07:14 +0000 (+0000) Subject: re PR debug/46240 (ice in maybe_register_def) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=23d5ed5dcf5305653fc67dddf0a2ea53ca81add6;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af91c9a4a80..fc8e90ca95a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-01-19 Alexandre Oliva + + 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 PR debug/47079 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0962b7020b0..332b1eb1f22 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-01-19 Alexandre Oliva + + PR debug/46240 + * g++.dg/debug/pr46240.cc: New. + 2011-01-19 Jakub Jelinek PR c++/47303 diff --git a/gcc/testsuite/g++.dg/debug/pr46240.cc b/gcc/testsuite/g++.dg/debug/pr46240.cc new file mode 100644 index 00000000000..c12a6988af8 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/pr46240.cc @@ -0,0 +1,172 @@ +// { dg-do compile } +// { dg-options "-O3 -g" } + +template +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 +struct U +{ + static T epsilon () throw (); +}; +template +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 ::W (get_size (s))) {} + int capacity () { return slice_len; } + int get_size (S); +}; +template +struct Z : public V +{ + Z () : V (S (0, 0)) {} + Z (int r, int c) : V (S (r, c)) {} +}; +template +struct A : public Z +{ + A () : Z () {} + A (int n, int m) : Z (n, m) {} +}; +template +struct B : public V +{ +}; +struct C : public A +{ + C () : A () {} + C (int r, int c) : A (r, c) {} +}; +struct D : public B +{ +}; +template +struct E +{ +}; +template +struct G : public E +{ +}; +struct H : public G +{ +}; +template +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 +struct J +{ + template < class U > void accum (U val) {} + operator R () { return R (); } +}; +template +struct K +{ + R max; + template void accum (U val) + { + double z = __builtin_fabs (val); + max = ::max (max, z); + } + operator R () { return max; } +}; +template +struct L +{ + unsigned num; + template void accum (U) {} + operator R () { return num; } +}; +template +void bar (V &v, R &res, S acc) +{ + for (int i = 0; i < v.capacity (); i++) + acc.accum ((i)); + res = acc; +} +template +void bar (B &v, R) +{ + R res; + bar (v, res, I ()); +} +template +R bar (A &v, R p) +{ + R res; + if (p == 2) + bar (v, res, I ()); + else if (p == 1) + bar (v, res, J ()); + else if (p == sizeof (float) ? (p) : foo (p)) + { + if (p > 0) + bar (v, res, K ()); + } + else if (p == 0) + bar (v, res, L ()); + return res; +} +template +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 +void +test (CT m, R p, VectorT) +{ + VectorT x; + R sqrteps (U ::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 ()); +} diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 8d31fe7607e..c425586a156 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.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);