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;
+ }

Reply via email to