transform_to_exit_first_loop of the parloops pass can appearantly
not handle (certain?) loops that were not header-copied.  Thus, better
assert we face a do-while-style loop before parallelizing it.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2012-03-08  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/46886
        * tree-flow.h (do_while_loop_p): Declare.
        * tree-ssa-loop-ch.c (do_while_loop_p): Export.
        * tree-parloops.c (parallelize_loops): Only parallelize do-while
        loops.

        * testsuite/libgomp.c/pr46886.c: New testcase.

Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h     (revision 184007)
--- gcc/tree-flow.h     (working copy)
*************** extern bool may_propagate_copy (tree, tr
*** 619,624 ****
--- 619,627 ----
  extern bool may_propagate_copy_into_stmt (gimple, tree);
  extern bool may_propagate_copy_into_asm (tree);
  
+ /* In tree-ssa-loop-ch.c  */
+ bool do_while_loop_p (struct loop *);
+ 
  /* Affine iv.  */
  
  typedef struct
Index: gcc/tree-ssa-loop-ch.c
===================================================================
*** gcc/tree-ssa-loop-ch.c      (revision 184007)
--- gcc/tree-ssa-loop-ch.c      (working copy)
*************** should_duplicate_loop_header_p (basic_bl
*** 104,110 ****
  
  /* Checks whether LOOP is a do-while style loop.  */
  
! static bool
  do_while_loop_p (struct loop *loop)
  {
    gimple stmt = last_stmt (loop->latch);
--- 104,110 ----
  
  /* Checks whether LOOP is a do-while style loop.  */
  
! bool
  do_while_loop_p (struct loop *loop)
  {
    gimple stmt = last_stmt (loop->latch);
Index: gcc/tree-parloops.c
===================================================================
*** gcc/tree-parloops.c (revision 184007)
--- gcc/tree-parloops.c (working copy)
*************** parallelize_loops (void)
*** 2183,2189 ****
          || loop_has_blocks_with_irreducible_flag (loop)
          || (loop_preheader_edge (loop)->src->flags & BB_IRREDUCIBLE_LOOP)
          /* FIXME: the check for vector phi nodes could be removed.  */
!         || loop_has_vector_phi_nodes (loop))
        continue;
        estimated = max_stmt_executions_int (loop, false);
        /* FIXME: Bypass this check as graphite doesn't update the
--- 2183,2192 ----
          || loop_has_blocks_with_irreducible_flag (loop)
          || (loop_preheader_edge (loop)->src->flags & BB_IRREDUCIBLE_LOOP)
          /* FIXME: the check for vector phi nodes could be removed.  */
!         || loop_has_vector_phi_nodes (loop)
!         /* FIXME: transform_to_exit_first_loop does not handle not
!            header-copied loops correctly - see PR46886.  */
!         || !do_while_loop_p (loop))
        continue;
        estimated = max_stmt_executions_int (loop, false);
        /* FIXME: Bypass this check as graphite doesn't update the
Index: libgomp/testsuite/libgomp.c/pr46886.c
===================================================================
*** libgomp/testsuite/libgomp.c/pr46886.c       (revision 0)
--- libgomp/testsuite/libgomp.c/pr46886.c       (revision 0)
***************
*** 0 ****
--- 1,28 ----
+ /* { dg-do run } */
+ /* { dg-options "-O -ftree-parallelize-loops=4 -fno-tree-ch 
-fno-tree-dominator-opts" } */
+ 
+ void abort(void);
+ 
+ int d[1024], e[1024];
+ 
+ int foo (void)
+ {
+   int s = 0;
+   int i;
+   for (i = 0; i < 1024; i++)
+     s += d[i] - e[i];
+   return s;
+ }
+ 
+ int main ()
+ {
+   int i;
+   for (i = 0; i < 1024; i++)
+     {
+       d[i] = i * 2;
+       e[i] = i;
+     }
+   if (foo () != 1023 * 1024 / 2)
+     abort ();
+   return 0;
+ }

Reply via email to