There's a simple mistake in gimple_duplicate_sese_region that causes all loop-header copied loops to be thrown away (but soon re-discovered, hopefully without somebody inbetween messing things up).
Fixed like the following, bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2014-02-05 Richard Biener <rguent...@suse.de> * tree-cfg.c (gimple_duplicate_sese_region): Fix ordering of set_loop_copy and initialize_original_copy_tables. Index: gcc/tree-cfg.c =================================================================== *** gcc/tree-cfg.c (revision 207497) --- gcc/tree-cfg.c (working copy) *************** gimple_duplicate_sese_region (edge entry *** 5879,5892 **** return false; } - set_loop_copy (loop, loop); - /* In case the function is used for loop header copying (which is the primary use), ensure that EXIT and its copy will be new latch and entry edges. */ if (loop->header == entry->dest) { copying_header = true; - set_loop_copy (loop, loop_outer (loop)); if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src)) return false; --- 5905,5915 ---- *************** gimple_duplicate_sese_region (edge entry *** 5897,5910 **** return false; } if (!region_copy) { region_copy = XNEWVEC (basic_block, n_region); free_region_copy = true; } - initialize_original_copy_tables (); - /* Record blocks outside the region that are dominated by something inside. */ if (update_dominance) --- 5920,5938 ---- return false; } + initialize_original_copy_tables (); + + if (copying_header) + set_loop_copy (loop, loop_outer (loop)); + else + set_loop_copy (loop, loop); + if (!region_copy) { region_copy = XNEWVEC (basic_block, n_region); free_region_copy = true; } /* Record blocks outside the region that are dominated by something inside. */ if (update_dominance)