This fixes PR58554, pattern recognition in loop distribution now needs to check whether all stmts are unconditionally executed.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2013-09-30 Richard Biener <rguent...@suse.de> PR tree-optimization/58554 * tree-loop-distribution.c (classify_partition): Require unconditionally executed stores for memcpy and memset recognition. (tree_loop_distribution): Calculate dominance info. * gcc.dg/torture/pr58554.c: New testcase. Index: gcc/tree-loop-distribution.c =================================================================== *** gcc/tree-loop-distribution.c (revision 203028) --- gcc/tree-loop-distribution.c (working copy) *************** classify_partition (loop_p loop, struct *** 1206,1212 **** && !SSA_NAME_IS_DEFAULT_DEF (rhs) && flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (rhs)))) return; ! if (!adjacent_dr_p (single_store)) return; partition->kind = PKIND_MEMSET; partition->main_dr = single_store; --- 1206,1214 ---- && !SSA_NAME_IS_DEFAULT_DEF (rhs) && flow_bb_inside_loop_p (loop, gimple_bb (SSA_NAME_DEF_STMT (rhs)))) return; ! if (!adjacent_dr_p (single_store) ! || !dominated_by_p (CDI_DOMINATORS, ! loop->latch, gimple_bb (stmt))) return; partition->kind = PKIND_MEMSET; partition->main_dr = single_store; *************** classify_partition (loop_p loop, struct *** 1222,1228 **** if (!adjacent_dr_p (single_store) || !adjacent_dr_p (single_load) || !operand_equal_p (DR_STEP (single_store), ! DR_STEP (single_load), 0)) return; /* Now check that if there is a dependence this dependence is of a suitable form for memmove. */ --- 1224,1232 ---- if (!adjacent_dr_p (single_store) || !adjacent_dr_p (single_load) || !operand_equal_p (DR_STEP (single_store), ! DR_STEP (single_load), 0) ! || !dominated_by_p (CDI_DOMINATORS, ! loop->latch, gimple_bb (store))) return; /* Now check that if there is a dependence this dependence is of a suitable form for memmove. */ *************** out: *** 1719,1724 **** --- 1723,1729 ---- { if (!cd) { + calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS); cd = new control_dependences (create_edge_list ()); free_dominance_info (CDI_POST_DOMINATORS); Index: gcc/testsuite/gcc.dg/torture/pr58554.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr58554.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr58554.c (working copy) *************** *** 0 **** --- 1,20 ---- + /* { dg-do run } */ + + extern void abort (void); + void __attribute__((noinline,noclone)) + clear_board(unsigned char *board, int board_size) + { + int k; + for (k = 0; k < 421; k++) + if (k < board_size ) + board[k] = 3; + } + int main() + { + unsigned char board[421]; + board[420] = 1; + clear_board (board, 420); + if (board[420] != 1) + abort (); + return 0; + }