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