The following fixes PR61438 - when moving the PHI insertion inhibiting code I forgot to guard it so that it only runs for PRE.
Bootstrap/regtest pending on x86_64-unknown-linux-gnu. Richard. 2014-06-10 Richard Biener <rguent...@suse.de> PR tree-optimization/61438 * tree-ssa-pre.c (eliminate_dom_walker): Add do_pre member. (eliminate_dom_walker::before_dom_children): Only try to inhibit insertion of IVs if running PRE. (eliminate): Adjust. (pass_pre::execute): Likewise. (pass_fre::execute): Likewise. * gcc.dg/torture/pr61438.c: New testcase. Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 211398) --- gcc/tree-ssa-pre.c (working copy) *************** eliminate_insert (gimple_stmt_iterator * *** 3992,4001 **** class eliminate_dom_walker : public dom_walker { public: ! eliminate_dom_walker (cdi_direction direction) : dom_walker (direction) {} virtual void before_dom_children (basic_block); virtual void after_dom_children (basic_block); }; /* Perform elimination for the basic-block B during the domwalk. */ --- 3992,4004 ---- class eliminate_dom_walker : public dom_walker { public: ! eliminate_dom_walker (cdi_direction direction, bool do_pre_) ! : dom_walker (direction), do_pre (do_pre_) {} virtual void before_dom_children (basic_block); virtual void after_dom_children (basic_block); + + bool do_pre; }; /* Perform elimination for the basic-block B during the domwalk. */ *************** eliminate_dom_walker::before_dom_childre *** 4192,4198 **** variable. In other cases the vectorizer won't do anything anyway (either it's loop invariant or a complicated expression). */ ! if (flag_tree_loop_vectorize && gimple_assign_single_p (stmt) && TREE_CODE (sprime) == SSA_NAME && loop_outer (b->loop_father)) --- 4195,4202 ---- variable. In other cases the vectorizer won't do anything anyway (either it's loop invariant or a complicated expression). */ ! if (do_pre ! && flag_tree_loop_vectorize && gimple_assign_single_p (stmt) && TREE_CODE (sprime) == SSA_NAME && loop_outer (b->loop_father)) *************** eliminate_dom_walker::after_dom_children *** 4434,4440 **** /* Eliminate fully redundant computations. */ static unsigned int ! eliminate (void) { gimple_stmt_iterator gsi; gimple stmt; --- 4438,4444 ---- /* Eliminate fully redundant computations. */ static unsigned int ! eliminate (bool do_pre) { gimple_stmt_iterator gsi; gimple stmt; *************** eliminate (void) *** 4448,4454 **** el_avail.create (0); el_avail_stack.create (0); ! eliminate_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); el_avail.release (); el_avail_stack.release (); --- 4452,4459 ---- el_avail.create (0); el_avail_stack.create (0); ! eliminate_dom_walker (CDI_DOMINATORS, ! do_pre).walk (cfun->cfg->x_entry_block_ptr); el_avail.release (); el_avail_stack.release (); *************** pass_pre::execute (function *fun) *** 4779,4785 **** gsi_commit_edge_inserts (); /* Remove all the redundant expressions. */ ! todo |= eliminate (); statistics_counter_event (fun, "Insertions", pre_stats.insertions); statistics_counter_event (fun, "PA inserted", pre_stats.pa_insert); --- 4784,4790 ---- gsi_commit_edge_inserts (); /* Remove all the redundant expressions. */ ! todo |= eliminate (true); statistics_counter_event (fun, "Insertions", pre_stats.insertions); statistics_counter_event (fun, "PA inserted", pre_stats.pa_insert); *************** pass_fre::execute (function *fun) *** 4864,4870 **** memset (&pre_stats, 0, sizeof (pre_stats)); /* Remove all the redundant expressions. */ ! todo |= eliminate (); todo |= fini_eliminate (); --- 4869,4875 ---- memset (&pre_stats, 0, sizeof (pre_stats)); /* Remove all the redundant expressions. */ ! todo |= eliminate (false); todo |= fini_eliminate (); Index: gcc/testsuite/gcc.dg/torture/pr61438.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr61438.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr61438.c (working copy) *************** *** 0 **** --- 1,48 ---- + /* { dg-do run } */ + + extern void abort (void); + + int a, c, **d, e, g; + static int b = 1; + + struct + { + int f0; + } f; + + void + foo () + { + int h, *i = &a; + for (; e;) + { + for (c = 0; c < 1; c++) + for (; b;) + ; + for (;;) + { + if (a) + { + for (; f.f0; f.f0++) + ; + if (g) + break; + } + for (h = 0; h < 2; h++) + { + i = *d; + if (!i) + abort (); + } + } + } + if (!i) + abort (); + } + + int + main () + { + foo (); + return 0; + }