I am testing the following patch to fix another case where call shrink-wrapping fails to update PHIs properly. The previous fix missed the case where the destination contained a degenerate PHI thus we can simply propagate those out.
Bootstrap and regtest running on x86_64-unknown-linux-gnu (for trunk where the testcase doesn't show the latent issue). I'll backport later. Richard. 2016-01-10 Richard Biener <rguent...@suse.de> PR tree-optimization/79034 * tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds): Propagate out degenerate PHIs in the joiner. * g++.dg/torture/pr79034.C: New testcase. Index: gcc/tree-call-cdce.c =================================================================== --- gcc/tree-call-cdce.c (revision 244260) +++ gcc/tree-call-cdce.c (working copy) @@ -805,7 +805,18 @@ shrink_wrap_one_built_in_call_with_conds if (EDGE_COUNT (join_tgt_in_edge_from_call->dest->preds) > 1) join_tgt_bb = split_edge (join_tgt_in_edge_from_call); else - join_tgt_bb = join_tgt_in_edge_from_call->dest; + { + join_tgt_bb = join_tgt_in_edge_from_call->dest; + /* We may have degenerate PHIs in the destination. Propagate + those out. */ + for (gphi_iterator i = gsi_start_phis (join_tgt_bb); !gsi_end_p (i);) + { + gphi *phi = i.phi (); + replace_uses_by (gimple_phi_result (phi), + gimple_phi_arg_def (phi, 0)); + remove_phi_node (&i, true); + } + } } else { Index: gcc/testsuite/g++.dg/torture/pr79034.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr79034.C (nonexistent) +++ gcc/testsuite/g++.dg/torture/pr79034.C (working copy) @@ -0,0 +1,52 @@ +/* { dg-do compile } */ + +extern "C" { + float sqrtf(float); +} + +class T { +public: + float floats[1]; + + inline float length() const { + return sqrtf(floats[0]); + } +}; + +void destruct(void *); + +class Container { + + T Ts[1]; + +public: + ~Container() { + destruct((void *)Ts); + } + + T& operator[](int n) { + return Ts[0]; + } +}; + +void fill(Container&); + +void doit() +{ + Container data; + float max = 10; + + int i, j, k; + + for (i = 0; i < 10; i++) { + for (j = 1; j < 10; j++) { + if (max < 5) + break; + fill( data); + max = data[0].length(); + for (k = 1; k < j; k++) { + max = 5; + } + } + } +}