The following patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64087
The patch was bootstrapped and tested on x86-64. Committed as rev. 218162. 2014-11-28 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/64087 * lra-lives.c (process_bb_lives): Add debug output. (lra_create_live_ranges): Don't remove dead insn on the second call of lra_create_live_ranges_1. 2014-11-28 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/64087 * gcc.dg/pr64087.c: New.
Index: lra-lives.c =================================================================== --- lra-lives.c (revision 218129) +++ lra-lives.c (working copy) @@ -971,14 +971,23 @@ process_bb_lives (basic_block bb, int &c live_pseudos_num++; if (! sparseset_bit_p (pseudos_live, j)) { - live_change_p = TRUE; + live_change_p = true; + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + " r%d is removed as live at bb%d start\n", j, bb->index); break; } } - live_change_p - = (live_change_p - || sparseset_cardinality (pseudos_live) != live_pseudos_num); - + if (! live_change_p + && sparseset_cardinality (pseudos_live) != live_pseudos_num) + { + live_change_p = true; + if (lra_dump_file != NULL) + EXECUTE_IF_SET_IN_SPARSESET (pseudos_live, j) + if (! bitmap_bit_p (df_get_live_in (bb), j)) + fprintf (lra_dump_file, + " r%d is added to live at bb%d start\n", j, bb->index); + } /* See if we'll need an increment at the end of this basic block. An increment is needed if the PSEUDOS_LIVE set is not empty, to make sure the finish points are set up correctly. */ @@ -1322,11 +1331,16 @@ lra_create_live_ranges (bool all_p, bool if (lra_dump_file != NULL) fprintf (lra_dump_file, "Live info was changed -- recalculate it\n"); /* Live info was changed on a bb border. It means that some info, - e.g. about conflict regs, calls crossed may be wrong, live - ranges. We need this info for allocation. So recalcualate it - again. */ + e.g. about conflict regs, calls crossed, and live ranges may be + wrong. We need this info for allocation. So recalculate it + again but without removing dead insns which can change live info + again. Repetitive live range calculations are expensive therefore + we stop here as we already have correct info although some + improvement in rare cases could be possible on this sub-pass if + we do dead insn elimination again (still the improvement may + happen later). */ lra_clear_live_ranges (); - bool res = lra_create_live_ranges_1 (all_p, dead_insn_p); + bool res = lra_create_live_ranges_1 (all_p, false); lra_assert (! res); } Index: testsuite/gcc.dg/pr64087.c =================================================================== --- testsuite/gcc.dg/pr64087.c (revision 0) +++ testsuite/gcc.dg/pr64087.c (working copy) @@ -0,0 +1,35 @@ +/* PR rtl-optimization/64087 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int printf (const char *, ...); + +int a[72], b, c, d, e; + +int +main () +{ + int h; + for (b = 0; b < 72; b++) + { + h = 1; + if (b) + h >>= 1; + a[b] = h; + } + for (; e; e++) + for (c = 0; c < 1;) + for (; d;) + { + printf ("0"); + int g; + for (b = 0; b < 72; b++) + { + g = 1; + if (b) + g >>= 1; + a[b] = g; + } + } + return 0; +}