This fixes PR51070 where we repace the partition <bb 5>: # g_224.0_23 = PHI <g_224.1_10(7), g_224.0_22(4)> D.2957_3 = g_92[g_224.0_23]; g_92[g_224.0_23] = 0; g_224.1_10 = g_224.0_23 + 1; if (g_224.1_10 != 0) goto <bb 7>; else goto <bb 6>;
<bb 6>: # g_95_I_lsm.15_29 = PHI <D.2957_3(5)> g_95[0] = g_95_I_lsm.15_29; g_224 = 0; goto <bb 3>; <bb 7>: goto <bb 5>; with a memset, throwing away the statement that loads D.2957_3 and thus causing an SSA name on the freelist to remain in the PHI node in BB6. We obviously cannot create a memset for such a partition. Bootstrap and regtest pending on x86_64-unknown-linux-gnu. Richard. 2011-11-10 Richard Guenther <rguent...@suse.de> PR tree-optimization/51070 * tree-loop-distribution.c (generate_builtin): Do not replace the loop with a builtin if the partition contains statements which results are used outside of the loop. (pass_loop_distribution): Verify and collect. * gcc.dg/torture/pr51070.c: New testcase. Index: gcc/tree-loop-distribution.c =================================================================== *** gcc/tree-loop-distribution.c (revision 181252) --- gcc/tree-loop-distribution.c (working copy) *************** static bitmap remaining_stmts; *** 63,68 **** --- 63,110 ---- predecessor a node that writes to memory. */ static bitmap upstream_mem_writes; + /* Returns true when DEF is an SSA_NAME defined in LOOP and used after + the LOOP. */ + + static bool + ssa_name_has_uses_outside_loop_p (tree def, loop_p loop) + { + imm_use_iterator imm_iter; + use_operand_p use_p; + + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def) + if (loop != loop_containing_stmt (USE_STMT (use_p))) + return true; + + return false; + } + + /* Returns true when STMT defines a scalar variable used after the + loop. */ + + static bool + stmt_has_scalar_dependences_outside_loop (gimple stmt) + { + tree name; + + switch (gimple_code (stmt)) + { + case GIMPLE_ASSIGN: + name = gimple_assign_lhs (stmt); + break; + + case GIMPLE_PHI: + name = gimple_phi_result (stmt); + break; + + default: + return false; + } + + return TREE_CODE (name) == SSA_NAME + && ssa_name_has_uses_outside_loop_p (name, loop_containing_stmt (stmt)); + } + /* Update the PHI nodes of NEW_LOOP. NEW_LOOP is a duplicate of ORIG_LOOP. */ *************** generate_builtin (struct loop *loop, bit *** 330,339 **** { gimple stmt = gsi_stmt (bsi); ! if (gimple_code (stmt) != GIMPLE_LABEL ! && !is_gimple_debug (stmt) ! && bitmap_bit_p (partition, x++) ! && is_gimple_assign (stmt) && !is_gimple_reg (gimple_assign_lhs (stmt))) { /* Don't generate the builtins when there are more than --- 372,389 ---- { gimple stmt = gsi_stmt (bsi); ! if (gimple_code (stmt) == GIMPLE_LABEL ! || is_gimple_debug (stmt)) ! continue; ! ! if (!bitmap_bit_p (partition, x++)) ! continue; ! ! /* If the stmt has uses outside of the loop fail. */ ! if (stmt_has_scalar_dependences_outside_loop (stmt)) ! goto end; ! ! if (is_gimple_assign (stmt) && !is_gimple_reg (gimple_assign_lhs (stmt))) { /* Don't generate the builtins when there are more than *************** fuse_partitions_with_similar_memory_acce *** 824,871 **** } } - /* Returns true when DEF is an SSA_NAME defined in LOOP and used after - the LOOP. */ - - static bool - ssa_name_has_uses_outside_loop_p (tree def, loop_p loop) - { - imm_use_iterator imm_iter; - use_operand_p use_p; - - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def) - if (loop != loop_containing_stmt (USE_STMT (use_p))) - return true; - - return false; - } - - /* Returns true when STMT defines a scalar variable used after the - loop. */ - - static bool - stmt_has_scalar_dependences_outside_loop (gimple stmt) - { - tree name; - - switch (gimple_code (stmt)) - { - case GIMPLE_ASSIGN: - name = gimple_assign_lhs (stmt); - break; - - case GIMPLE_PHI: - name = gimple_phi_result (stmt); - break; - - default: - return false; - } - - return TREE_CODE (name) == SSA_NAME - && ssa_name_has_uses_outside_loop_p (name, loop_containing_stmt (stmt)); - } - /* Returns true when STMT will be code generated in a partition of RDG different than PART and that will not be code generated as a builtin. */ --- 874,879 ---- *************** struct gimple_opt_pass pass_loop_distrib *** 1311,1316 **** 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! 0 /* todo_flags_finish */ } }; --- 1319,1325 ---- 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_ggc_collect ! | TODO_verify_ssa /* todo_flags_finish */ } }; Index: gcc/testsuite/gcc.dg/torture/pr51070.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr51070.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr51070.c (revision 0) *************** *** 0 **** --- 1,34 ---- + /* { dg-do compile } */ + + int + func_4 (int si1, int si2) + { + return si1; + } + + int + func_14 (int left, int right) + { + return 1; + } + + int + func_37 (int left, int right) + { + return left; + } + + int g_92[1024]; + int g_95[1024]; + int g_224; + int g_352[1024]; + int + func_9 () + { + for (; g_224; g_224 += 1) + { + g_95[0] = func_4 (func_37 (g_92[g_224], 0), 0); + g_92[g_224] = 0, g_352[g_224] = func_14 (0, 0); + } + return 0; + }