Hi! move_sese_region_to_fn moves a subset of the original loop tree to the dest_cfun (and adds the outermost loop new). Now, some loops might have non-zero orig_loop_num field. In the caller that is fine, if the orig_loop_num loop is moved, then get_loop will just return NULL and we'll clear it later. But if a loop with orig_loop_num != 0 is moved into the dest_cfun, where we create new numbers for the loops, orig_loop_num might be too large for the larray vector, or might point to an unrelated loop.
The following patch goes through all the loops moved into dest_cfun and if they have non-zero orig_loop_num, it tries to remap them into a new number if it points to a loop that was also moved to dest_cfun, or clears it otherwise. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-12-05 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/81945 * cfgloop.h (FOR_EACH_LOOP_FN): Use FN instead of hardcoding fn. * tree-cfg.c (move_sese_region_to_fn): If any of the loops moved to dest_cfun has orig_loop_num set, either remap it to the new loop number if the loop got moved too, or clear it. * gcc.dg/graphite/pr81945.c: New test. --- gcc/cfgloop.h.jj 2017-11-27 18:52:20.000000000 +0100 +++ gcc/cfgloop.h 2017-12-05 16:00:07.771838975 +0100 @@ -766,7 +766,7 @@ loop_iterator::~loop_iterator () (LOOP) = li.next ()) #define FOR_EACH_LOOP_FN(FN, LOOP, FLAGS) \ - for (loop_iterator li(fn, &(LOOP), FLAGS); \ + for (loop_iterator li(FN, &(LOOP), FLAGS); \ (LOOP); \ (LOOP) = li.next ()) --- gcc/tree-cfg.c.jj 2017-12-04 20:10:29.000000000 +0100 +++ gcc/tree-cfg.c 2017-12-05 15:54:53.000000000 +0100 @@ -7468,6 +7468,8 @@ move_sese_region_to_fn (struct function loops->state = LOOPS_MAY_HAVE_MULTIPLE_LATCHES; set_loops_for_fn (dest_cfun, loops); + vec<loop_p, va_gc> *larray = get_loops (saved_cfun)->copy (); + /* Move the outlined loop tree part. */ num_nodes = bbs.length (); FOR_EACH_VEC_ELT (bbs, i, bb) @@ -7514,6 +7516,20 @@ move_sese_region_to_fn (struct function loop->aux = current_loops->tree_root; loop0->aux = current_loops->tree_root; + /* Fix up orig_loop_num. If the block referenced in it has been moved + to dest_cfun, update orig_loop_num field, otherwise clear it. */ + struct loop *dloop; + FOR_EACH_LOOP_FN (dest_cfun, dloop, 0) + if (dloop->orig_loop_num) + { + if ((*larray)[dloop->orig_loop_num] != NULL + && get_loop (saved_cfun, dloop->orig_loop_num) == NULL) + dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num; + else + dloop->orig_loop_num = 0; + } + ggc_free (larray); + pop_cfun (); /* Move blocks from BBS into DEST_CFUN. */ --- gcc/testsuite/gcc.dg/graphite/pr81945.c.jj 2017-12-05 16:07:12.375610782 +0100 +++ gcc/testsuite/gcc.dg/graphite/pr81945.c 2017-12-05 16:07:24.925456255 +0100 @@ -0,0 +1,21 @@ +/* PR tree-optimization/81945 */ +/* { dg-do compile { target pthread } } */ +/* { dg-options "-O3 -ftree-parallelize-loops=2 -floop-nest-optimize" } */ + +unsigned long int v; + +void +foo (int x, int y, long int *a) +{ + do + { + int **b; + + while (y != 0) + ; + v *= 2; + **b = *a; + ++x; + } + while (x < 1); +} Jakub